ios – UITableView在插入行后滚动到顶部

我有一个可扩展的UITableView.当节拍片段时,它们会以动画展开或折叠(滚动).我的问题是在扩展或折叠标题时有一个奇怪的动画. UITableView滚动到顶部,然后转到tapped单元格.此外,当没有扩展的单元格时,有时候,它不会滚动到顶部,并且UITableView的顶部标题和顶视图之间有一个很大的空间.

我的问题是我需要滚动到扩展部分,并摆脱滚动到顶部的错误.

我尝试了下面的解决方案,但没有为我工作:
prevent table view to scrolling top after insertRows

对于下面的问题,它看起来也是同样的问题,但无法弄清楚如何实现它.
Why does my UITableView “jump” when inserting or removing a row?

我如何切换选择:

func toggleSection(header: DistrictTableViewHeader, section: Int) {
    print("Trying to expand and close section...")
    // Close the section first by deleting the rows
    var indexPaths = [IndexPath]()
    for row in self.cities[section].districts.indices {
        print(0, row)
        let indexPath = IndexPath(row: row, section: section)
        indexPaths.append(indexPath)
    }

    let isExpanded = self.cities[section].isExpanded
    if(isExpanded){
        AnalyticsManager.instance.logPageEvent(screenName: analyticsName!, category: "Button", action: Actions.interaction, label: "\(self.cities[section].name) Collapse Click")
    }else{
        AnalyticsManager.instance.logPageEvent(screenName: analyticsName!, category: "Button", action: Actions.interaction, label: "\(self.cities[section].name) Expand Click")
    }
    self.cities[section].isExpanded = !isExpanded

    // This call opens CATransaction context
    CATransaction.begin()
    // This call begins tableView updates (not really needed if you only make one insertion call, or one deletion call, but in this example we do both)
    tableView.beginUpdates()
    if isExpanded {

        tableView.deleteRows(at: indexPaths, with: .automatic)
    } else {
        tableView.insertRows(at: indexPaths, with: .automatic)
    }
    // completionBlock will be called after rows insertion/deletion animation is done
    CATransaction.setCompletionBlock({
        // This call will scroll tableView to the top of the 'section' ('section' should have value of the folded/unfolded section's index)
            if !isExpanded{
                self.tableView.scrollToRow(at: IndexPath(row: NSNotFound, section: section) /* you can pass NSNotFound to scroll to the top of the section even if that section has 0 rows */, at: .top, animated: true)
            }
    })

    if self.scrollToTop(){
        self.tableView.setContentOffset(.zero, animated: true)
    }
    // End table view updates
    tableView.endUpdates()


    // Close CATransaction context
    CATransaction.commit()

}

private func scrollToTop() -> Bool{
    for sec in self.cities{
        if(sec.isExpanded){
            return false
        }
    }
    return true
}

我正在给予细胞高度;

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

我如何声明标题;

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let header = DistrictTableViewHeader()
    header.isColapsed = !self.cities[section].isExpanded
    header.customInit(title: self.cities[section].name, section: section, delegate: self)
    return header
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 60
}

编辑:此问题中的解决方案(将估计高度设置为0)看起来像插入行时工作.但是,删除行时仍然有bug.底部标题转到tableview的中心,然后在折叠标题后转到底部.

iOS 11 Floating TableView Header

最佳答案 您可以尝试使用以下代码.只需获取tableview的最后一个内容偏移量.然后执行更新并重新分配内容偏移量.

let lastOffset = tableView.contentOffset
self.tableView.beginUpdates()
self.tableView.layer.removeAllAnimations()
self.tableView.endUpdates()
tableView.contentOffset = lastOffset
点赞