【问题标题】:UITableView Reload Rows unnaturally jerking the TableView in iOS 11.2UITableView Reload Rows 在 iOS 11.2 中不自然地拉动 TableView
【发布时间】:2017-12-07 08:09:07
【问题描述】:

在使用 iOS 11.2 更新新的 XCODE 9.2 后,通过调用

出现了奇怪的问题
let indexPath = IndexPath(item: 0, section: 1)
self.tableViewHome.reloadRows(at: [indexPath], with: .none)

这会导致整个 TableView 出现不必要的抖动,之前这些代码很好。

适用于 iOS 11.2 的 GIF 图片

适用于 iOS 11.1 的 GIF 图片

如何停止这种抽搐,我只需要在两个单元格中重新加载表格视图中的一个单元格。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 我不认为这是由于 iOS 11。在 cellForRow 中,您必须在单元格视图中添加或删除视图。这通常是混蛋的原因。
  • @Mohammad Sadiq:我添加了两个 gif 图像,一个在带有 iOS 11.1 的 xcode 9.1 中,另一个是带有 ios 11.2 的 Xcode 9.2,相同的代码已在不同机器的两个 xcode 中执行。但是在 11.2 中它会抖动,但在 11.1 中不会,这对我来说也很奇怪。
  • @AbhishekMitra,iOS11.2 好运吗?我面临同样的问题。它在 iOS11.1 中没有抖动,但现在在 11.2 中显示抖动。如果你运气好,请告诉我。
  • @torap 修复后我没有做任何研究.. 你得到了什么?你能显示gif和你的代码sn-p吗?
  • @AbhishekMitra,查看此giphy.com/gifs/ios11-3ohjV9asyToN6M8tu8

标签: ios swift uitableview ios11 uitableviewrowaction


【解决方案1】:

我的理解是,如果您真的想使用自动调整大小的单元格(并且所有单元格的大小不同),那么上述解决方案不适用于 iOS 11.2,所以我尝试如下:

声明变量来存储单元格的高度

var cellHeightDictionary: NSMutableDictionary // To overcome the issue of iOS11.2

在viewDidLoad中初始化,

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 125
    cellHeightDictionary = NSMutableDictionary()
}

并像下面这样使用:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeightDictionary.setObject(cell.frame.size.height, forKey: indexPath as NSCopying)
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    if cellHeightDictionary.object(forKey: indexPath) != nil {
        let height = cellHeightDictionary.object(forKey: indexPath) as! CGFloat
        return height
    }
    return UITableViewAutomaticDimension
}

这对我有用,希望这对你也有帮助

【讨论】:

  • 感谢 Torap 对其进行调查。我通过投票感谢您的回答。但是我在另一个答案中已经为 ios 11.2 解决了这个问题,您可以查看它。
【解决方案2】:

我终于得到了答案,我必须使用 UITableView 的委托方法,即

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {

            return UITableViewAutomaticDimension
    }

在通过返回 UITableViewAutomaticDimension 放置此方法后,它会停止对 iOS 11.2 的抽搐。

【讨论】:

  • 这适用于 11.1 但不适用于 11.2。 iOS 11.2 中仍然存在问题
【解决方案3】:

**适用于 ios 11.2.* **

tableView.rowHeight = UITableViewAutomaticDimension in viewDidLoad()

添加estimatedHeightForRowAt

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {

        if indexPath.row == 0{

            return firstCellHeight()
        }
        else{

            return UITableViewAutomaticDimension
        }
}

firstCellHeight 是我的第一个单元格高度

func firstCellHeight() -> CGFloat{

    if UIDevice.Display.typeIsLike == UIDevice.DisplayType.ipad{

        return 400

    }else if UIDevice.Display.typeIsLike == UIDevice.DisplayType.iphone7plus{

        return 230

    }else if UIDevice.Display.typeIsLike == UIDevice.DisplayType.iphoneX{

        return 200

    }else{

        return 180
    }
}

并且不要使用:reloadRows

    let indexPath = IndexPath(item: 1, section: 0)
    tableView.reloadRows(at: [indexPath], with: .none)

改为使用reloadData,即tableView.reloadData()

最后在您需要操作的地方,使用下面的代码:

let indexPath0 = IndexPath(item: 0, section: 0)
        if !((tableView.indexPathsForVisibleRows?.contains(indexPath0))!) {
            print("Not Visible")

            self.tableView.setContentOffset(CGPoint(x:0, y:firstCellHeight() ), animated: false)
        }

【讨论】:

  • tableView.setContentOffset之后使用tableView.reloadData()
  • 如果我需要重新加载多个单元格而不是整个 tableview,为什么要使用 reloadData 而不是 reloadRows?
  • 谢谢你帮助了我。为我工作。谢谢
【解决方案4】:

我有同样的问题。我做错了一件事。 选择了情节提要中的自动行高和自动估计高度,并在代码中实现了 heightForRowAt 方法。我取消选中自动行高,只实现了 heightForRowAt 方法。它解决了我的问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2019-02-20
    相关资源
    最近更新 更多