我有一个可扩展的UITableView 点按各个部分时,它们会随着动画(滚动)展开或折叠。 我的问题是,展开或折叠标题时出现奇怪的动画。 UITableView滚动到顶部,然后转到被点击的单元格。 另外,有时没有展开的单元格时,它不会滚动到顶部,并且UITableView顶部标题和顶部视图之间有很大的空间。

我的问题是我需要滚动到展开的部分,也要摆脱滚动到顶部的错误。

我尝试了以下解决方案,但对我没有用: 防止表格视图在insertRows之后滚动到顶部

它也与下面的问题看起来一样,但是无法弄清楚如何实现它。 为什么插入或删除行时UITableView会“跳”?

如何切换选择:

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)中的解决方案看起来像在插入行时工作。 但是,删除行时我仍然有错误。 底部标题转到表格视图的中心,然后在折叠标题之后转到底部。

iOS 11浮动TableView标头

#1楼 票数:1

您可以尝试使用以下代码。 只需获取表视图的最后一个内容偏移即可。 然后进行更新并重新分配内容偏移量。

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

#2楼 票数:0

在我的代码中,我使用tableView.reloadData()来扩展和收缩特定部分,而不是tableView.beginUpdates()tableView.endUpdates() ,可以在需要提供部分扩展时调用reloadData。

这样就不会出现动画滚动到顶部的问题。 并在我的项目中运行良好,在该项目中,必须单击该部分中包含的按钮,才能显示该部分中的特定行数。

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0 {
        return 1
    }
// Ignore the If Else statements it's just when do you need expansion of section.
    else {
        if showMore == true {
            return self.userPoints.rewardsData[section - 1].count - 1
        }
        else {
            return 0
        }
    }
}

同样不要忘记相应增加或减少该特定部分的行数。
前一行很重要,可以避免崩溃。

#3楼 票数:0

swift3及以上的简单解决方案

使用以下扩展名作为

例如:tableViewOutlet.tableViewScrollToBottom(动画:true)

extension UITableView {

    func tableViewScrollToBottom(animated: Bool) {

        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {

            let numberOfSections = self.numberOfSections
            let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
            if numberOfRows > 0 {
                let indexPath = IndexPath(row: 0, section: 0)
                self.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.top, animated: animated)
            }
        }
    }
}

#4楼 票数:0

我也面临着同样的问题,但是在阅读了一些教程以及研究与分析后,我发现此问题的发生是由于在单元格的表格视图计数高度从0扩展到120(根据您的单元格高度)时展开单元格的高度。 在我的情况下,我使用估计的单元格高度解决了该问题。

希望对您有所帮助,谢谢

  ask by Emre Önder translate from so

未解决问题?本站智能推荐:

1回复

插入更多行时,UITableView滚动到顶部

在我的代码中,我重写了tableView:willDisplayCell ,当显示最后一行时,我开始加载更多数据。 当这些数据输入时,我调用insertRowsAtIndexPaths添加行。 这通常可以正常工作(表视图的滚动位置不变),但是我注意到,如果我过度滚动而不放开(滚动到表视图
3回复

滚动到顶部UITableView,双击UITabBarItem

我想在他们的列表中模拟twitter或instagram的行为: 在UITabBarItem中双击时,列表将滚动到顶部。 有人知道我该怎么做? 我的UITabBarController中有4个项目,所有这些都是列表,所以我想为所有人做这件事。 问题是当我在mi列表的推送视图中点击
1回复

UITableView 是否滚动到顶部?

如何确定 UITableView 当前是否位于其数据的顶部? 我知道我可能会在滚动后收到警报,但我需要它用于静态 UI 元素而不是一次性触发事件。
3回复

调用reloadData后,UITableView动态单元格高度滚动到顶部

我的tableView中有动态单元格高度 我想和whatsapp应用程序(分页)一样,我想加载25乘25行,所以当用户在顶部滚动时,我想加载新数据但我想保持相同的滚动位置,这就是我做的 我遇到的问题是在我到达我的tableview之后它调用reloadData但是tableVie
1回复

在UITableView中滚动到顶部后,CAGradientLayer的位置错误。 迅速

我需要在特定UITableViewCell的底部阴影。 我做到了,但是当我滚动到底部时,它工作正常,当我滚动到顶部时,阴影位置错误,并且出现在UITableViewCell的顶部。 我尝试了几种方法,但对我不起作用。 我读了这个问题 ,这个问题我该如何解决? 我也尝试了以下功能
3回复

UITableView使用tableView标头中的SearchController滚动到顶部

所以我有一个tableView。 它的标题是一个UISearchController,它隐藏了导航控制器。 我希望当用户在搜索控制器上搜索或点击“取消”时,将该tableView滚动到顶部。 问题是 实际上滚动到tableView的顶部,在这种情况下,它是SearchContr
2回复

UITableView deleterows滚动到顶部

我进行了查询以删除UITableView中的指定行,但是当deleteRows称为UITableView滚动到顶部时出现问题,那么如何防止其滚动到顶部? 以及为什么它滚动到顶部! 我尝试调用一个方法来强制其向下滚动,但在返回remove代码后,tableview首先滚动至顶部
2回复

UITableView当单元格滚动到顶部时,单元格将固定在顶部

在TableView Middle中,当在tableview中滚动时,一个“Popular | Latest | Top Sales | Price”,中间单元格将固定在顶部。 那么,如何使用UITableView这样做? 下面的样本照片 照片样本第一 照片样本第二