繁体   English   中英

从 iOS 11 搜索控制器导航时不需要的 UITableView 重新加载动画

[英]Unwanted UITableView reload animation when navigating from iOS 11 search controller

我有一个带有包含聊天列表的表视图的视图控制器,一个嵌入在导航项中的搜索控制器(iOS 11 功能)

let searchController = UISearchController(searchResultsController: nil)
searchController.dimsBackgroundDuringPresentation = false
navigationItem.searchController = searchController
definesPresentationContext = true

当用户点击表视图中的聊天时,应用程序会推送一个新的视图控制器和另一个包含该聊天消息的表视图。 这就像它应该的那样工作:

在此处输入图像描述

问题是,当用户激活搜索控制器,找到一些聊天并点击它时,包含带有聊天消息的表视图的推送视图控制器会对不应该发生的表视图执行一些非常奇怪的动画

在此处输入图像描述

我在实际导航之前加载数据,并在viewDidLoad中仅使用表视图上的reload()将其绑定到表视图。 有问题的表视图使用自动布局和自定义单元格。

这个问题非常类似于调用 reloadData 时 UITableView 有不需要的动画,但对我来说它只发生在 iOS 11 搜索控制器处于活动状态时。

编辑:如果我删除tableView.rowHeight = UITableViewAutomaticDimension并使用固定高度func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat问题仍然存在

如果您只是在推送新的 viewController 之前隐藏 searchBar,那么它可能会解决您的问题。

您需要为 searchBarCancelButton 创建一个全局变量,并在搜索内容时从其子视图中找到取消按钮

let buttons = searchController.searchBar.subviews.first?.subviews.filter { (view) -> Bool in
            return NSStringFromClass(view.classForCoder) == "UINavigationButton"
        } as? [UIButton]
        searchBarCancelButton = buttons?.first

然后你可以手动取消它。

self.searchBarCancelButton?.sendActions(for: .touchUpInside)

您可以尝试在出列并设置单元格内容后立即调用cell.layoutIfNeeded()

iOS 11 彻底改进了安全区域 API,包括滚动视图插入调整行为,忽略时可能会导致不需要的动画。 因此,禁用带有不需要动画的滚动视图的自动内容插入调整:

if #available(iOS 11.0, *) {
    tableView.contentInsetAdjustmentBehavior = .never
} else {
    // < iOS 11 logic
}

就个人而言,我会在展示新的视图控制器之前简单地隐藏 searchView 控制器。 (例如,将 UIView.animates 与完成处理程序一起使用)

我不会尝试进一步调查,因为自 iOS11 以来,安全区域管理中存在一个深奥的问题。 错误? :)

甚至启动屏幕布局也没有得到正确处理。 很多专业标志在发布时都错过了中间部分!

不要在viewDidLoadviewWillAppear中调用reloadData()方法。 而不是在viewDidLoad中使用空数据重新加载您的 tableView,这样您的tableView将不显示任何内容,然后在您的viewDidAppear中调用reloadData()方法来加载您的所有聊天记录。 这将限制您的 tableView 加载不需要的动画。

var shouldShowEmpty = true

func viewDidLoad() {
    super.viewDidLoad()
    tableView.reloadData()
}
func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    shouldShowEmpty = false
    tableView.reloadData()
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if shouldShowEmpty {
            return 0
        }
        return yourArray.count
    }

根据附件,看起来由于自动布局,单元格元素的高度为零( UILabel or UIImageView )然后当表格视图重新加载时它突然获取单元格内的数据,从而增加其高度(自动尺寸或其他)导致此动画.

尝试在没有动画的情况下推送它或尝试设置修复单元格元素的高度和宽度并检查它是否仍在显示此动画。

您是否在不调用 UISearchBar 的情况下进行检查,如果您在任何单元格上选择相同的动画正在发生? 或者您是否尝试删除 UISearchbar 并选择单元格并检查动画部分?

请分享您的代码,以便我们看得更清楚。

我遇到过类似的问题,我相信解决方案是一样的。 键盘导致了问题,更正确的是,keyboardWillHideNotification 触发器。 您在底部有文本字段,它可能会监听键盘显示/隐藏的通知,如果您为底部约束设置动画,则触发 layoutIfNeeded() 以便您的键盘不会与您的文本字段重叠。 因此,当您在搜索文本字段中完成搜索时,会在不需要的时间触发 keyboardWillHideNotification。 我通过调用解决了我的问题:

resignFirstResponder()

对于导致此事件的文本字段。 在我的例子中,那是在你按下按钮之后,我相信它在搜索表视图中的 didSelect tableView 单元格中。

如果您在这个问题上仍然很活跃,请告诉我您是否设法解决了它。 我为了解决这个问题而伤透了脑筋,这显然是如此简单明了。

  • 在 VC2 中,在重新加载表之前尝试延迟功能

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { tableView.reloadData }

要不然

  • 在 VC1 中, didSelect在推送到 VC2 之前退出搜索控制器的第一响应者

要么

  • 在 VC1 中, didSelect退出搜索控制器的第一响应者,并在推送到 VC2 之前设置延迟

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM