UITableView 和 UIRefreshControl 因未知原因被下移

Posted

技术标签:

【中文标题】UITableView 和 UIRefreshControl 因未知原因被下移【英文标题】:UITableView and UIRefreshControl being moved down for unknown reason 【发布时间】:2015-03-24 19:04:24 【问题描述】:

我的应用中有一个 UITableViewController 并添加了一个 UIRefreshControl。然而,有时(我不确定如何重现这种情况,它时不时发生),我在表格视图的顶部得到一些额外的空白,刷新控件甚至在其下方偏移。

这就是它的样子(左侧空闲,右侧被拉下):

我不知道是什么原因造成的。在我的 viewdidload 中,我只是实例化了刷新控件并调用了一个设置属性标题的更新函数。正如我在别处所读到的,我已将向表视图添加刷新控件移动到 viewDidAppear 中。这段代码是这样的:

override func viewDidLoad() 
    super.viewDidLoad()
    self.refreshControl = UIRefreshControl()

    updateData()


override func viewDidAppear(animated: Bool) 
    refreshControl!.addTarget(self, action: "updateData", forControlEvents: UIControlEvents.ValueChanged)
    tableView.insertSubview(self.refreshControl!, atIndex: 0)


func updateData() 
    //...
    ServerController.sendParkinglotDataRequest() 
        (sections, plotList, updateError) in
        //...

        // Reload the tableView on the main thread, otherwise it will only update once the user interacts with it
        dispatch_async(dispatch_get_main_queue(),  () -> Void in
            self.tableView.reloadData()

            // Update the displayed "Last update: " time in the UIRefreshControl
            let formatter = NSDateFormatter()
            formatter.dateFormat = "dd.MM. HH:mm"
            let updateString = NSLocalizedString("LAST_UPDATE", comment: "Last update:")
            let title = "\(updateString) \(formatter.stringFromDate(NSDate()))"
            let attributedTitle = NSAttributedString(string: title, attributes: nil)
            self.refreshControl!.attributedTitle = attributedTitle
        )
    

【问题讨论】:

你有没有试过去掉uirefreshcontrol,测试一下问题是否依然存在?您的视图层次结构如何?您的视图控制器视图中是否有其他子视图位于表格视图下方? tableview 下方没有其他视图,只有导航栏和 tableview 以及 tableview 单元格。除了刷新控件之外,它们都在情节提要中进行了配置。我将删除刷新控件并查看问题是否仍然存在,但调试起来相当困难,因为此问题很少发生。 哦,等等,那行“tableView.insertSubview”...我在开始使用 UITableViewController 之前就有了,并且读到 UIRefreshControl 不应该像在普通 UITableViews 中那样使用。在这种情况下肯定不需要,这可能是问题吗? 【参考方案1】:

是否需要将刷新控件添加为tableView的子视图?我认为您需要做的就是分配 self.refreshControl。根据文档:

此属性的默认值为 nil。

为该属性分配一个刷新控件会将控件添加到 视图控制器的关联接口。您无需设置 在将其与视图关联之前刷新控件的框架 控制器。视图控制器更新控件的高度和宽度 并适当地设置它的位置。

viewDidAppear 中添加子视图可能会多次执行。如果您从单元格中推送控制器并弹回,这将再次被调用。可能是 insertSubview 检查刷新是否已经有父级并首先将其删除,因此可能不是您的问题。您应该只在控制器第一次出现时进行插入。

updateData 也可以被多次添加。

所以我认为您只需要分配self.refreshControl,然后像现在使用addTarget 一样为刷新操作添加一个处理程序,但这次在self.refreshControl 上执行。

您也可以从情节提要中完成所有这些操作。在情节提要中,您选择 UITableViewController 并在属性检查器上简单地将 Refreshing 属性设置为启用。这会将 UIRefreshControl 添加到表中,您可以在视图层次结构中看到它。然后,您可以像往常一样简单地按 CTRL 将刷新控件拖动到 .h 文件中,并为 valueChange 添加一个动作,当您下拉表格中的刷新控件时将触发该动作。

【讨论】:

我相信你可能是对的,我开始将刷新控件作为子视图添加到普通的 UITableView,然后才将我的视图控制器重构为 UITableViewController。但我再也没有真正想过那条线。这有点难以测试,因为问题只是不时出现,但这似乎是合乎逻辑的。不过,我将如何在情节提要中添加处理程序?故事板中并不真正存在刷新控件。 更新了解释如何在情节提要中添加 UIRefreshControl 的答案。它就像在属性检查器中启用刷新一样简单,它会为您添加一个。然后,您可以使用 CTRL 将操作添加到 .h 中。有了它,您可以删除所有代码并执行操作。 故事板是我的“解决方案”。太糟糕了,我仍然找不到任何解释为什么会发生这种情况。我正在对苹果的文档做这件事,但它给出了这个讨厌的 UI 错误【参考方案2】:

好吧,我相信您所描述的行为可能不一定是由刷新控件引起的。 根据您的表格视图下方没有任何其他子视图的事实,我建议您尝试在表格视图下方放置一个“假”视图。我通常更喜欢边长为 0 的空标签。

我也遇到过类似的问题,在某些情况下我的表格视图插图被破坏了。一旦我使用这个“假”子视图,问题就消失了。我也在其他一些线程中读到过这个问题。解决方案是这样的。似乎是一个奇怪的行为/错误。

试一试:)

【讨论】:

在 UITableViewController 的表格视图上方添加一些东西似乎真的不可能?似乎可行,但我无法在其中获得标签:D 你是对的,我以为你在使用 UIViewController。当我阅读你的问题时,我没有看到这一点。但请记住这项工作,以防您在“普通”视图控制器中有一个表格视图。

以上是关于UITableView 和 UIRefreshControl 因未知原因被下移的主要内容,如果未能解决你的问题,请参考以下文章

UINavigationBar.prefersLargeTitles 打开时的错误 UIRefreshControl 行为

获取 `UIRefreshControl` 到 `UITableViewController` 内容上方的北边,而不是在标题下?

搜索栏行为类似于原生联系人应用程序,但具有刷新控件

UITableView backgroundColor 和 UITableView.appearance

UIView 与 UITableview 和 UIImageview,使用 reloadData 访问 UITableview

UITableView 和 numberOfRowsInSection 崩溃