UITableView滚动到不需要的索引或位置

问题描述 投票:0回答:4

基本上任务是加载新的API响应,因为用户在UITableView中向下滚动而不停止用户交互并维持当前位置(Facebook和Instagram等实时源)。

我想要做的是解析然后在UITableView中使用自定义单元格查看Rest API的响应。

问题在于,当用户滚动到底部时,进行API调用并且表视图滚动到用户所在的其他位置。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return array.count;
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "xxxxx", for:indexPath) as! xxxxxxxx

    return cell;
}



func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    if scrollView == tableView {
        if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height) {
            print("Scroll Ended")
            fetchDataFromApi()
        }
    }
}


func fetchDataFromApi() {

    let jsonUrlString = "xxxxxxx"


    guard let url = URL(string: jsonUrlString) else {
        return
    }

    print(url)

    URLSession.shared.dataTask(with: url) {(data,response,err) in

        guard let data = data else {
            return
        }
        do {
            let apiResponseData = try JSONDecoder().decode(ApiResponse.self, from: data)

            if apiResponseData.httpStatusCode == HttpStatusCode.OK {

                if let apiResponse = apiResponseData.data{
                    self.array.append(contentsOf: apiResponse)
                }


                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }

            }
            else {
                print("API Response Error : \(apiResponseData.httpStatusCode) \(apiResponseData.errorMessage)")
            }
        }catch let jsonErr {
            print("Serialization Error \(jsonErr)")
        }
        }.resume()
}}
ios uitableview swift3 scroll scrollview
4个回答
0
投票

试试这个

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "xxxxx", for:indexPath) as! xxxxxxxx

    let lastRowIndex = tableView.numberOfRows(inSection: tableView.numberOfSections-1)

    if (indexPath.row == lastRowIndex - 1) {
         //print("last row selected")
        fetchDataFromApi()
    }

    return cell;
}

如果您正在使用它,则无需调用此方法

scrollViewDidEndDragging


0
投票

尝试insertCellAtIndexPath替换tableview.reloadData() in

if let apiResponse = apiResponseData.data{
                self.array.append(contentsOf: apiResponse)
            }


            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

......


0
投票

有几种方法可以实现这一点。据我所知,最有利的是实现一个分页API并在UITableView的最后一项后调用API。你可以使用:

public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let botEdge = scrollView.contentOffset.y + scrollView.frame.size.height;

if (botEdge >= scrollView.contentSize.height)
{
// Call API and reload TableView on completion handler.
}
}

在API方法的完成处理程序上调用tableView reload。

或者你可以稍微尴尬的方式做到这一点:

public var indexPathsForVisibleRows: [NSIndexPath]? { get }

获取当前可见单元格的索引路径数组,并在使用以下命令重新加载UITableView后滚动到索引:

tableView.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.None, animated: false)

0
投票

这是因为我在表格视图中设置了动态单元格大小

© www.soinside.com 2019 - 2024. All rights reserved.