UITableView - 在viewDidAppear之前滚动到底部

Rod*_*uiz 6 uitableview ios swift

如果标题不明显,我想要的应该是简单的,tableView当用户第一次看到它时(在他看到它之前,没有动画之前)开始滚动到底部.

所以,我知道这已经得到了几次回答,但这些解决方案似乎都没有发挥作用.为了给出一些上下文,我现在使用的是Swift,autolayout和最新版本的iOS.

约束

我需要支持一些事情:

  1. 在用户看到它之前加载它(显然没有动画).
  2. 动态单元格高度,即它们的高度由UILabel(如消息传递应用程序 - 在故事板中使用自动布局)确定.
  3. UITableView在里面UIScrollView(UIScrollView水平UITableView滚动并垂直滚动).
  4. UITableView是在childViewController,即,我把它添加到主UIViewController(其中,出于某种原因,使得viewWillAppear不会被调用- viewDidAppear仍称).

我将总结一下我的尝试:

至于实施:

  1. tableView.contentOffset = CGPoint(x: 0, y: CGFloat.max

  2. tableView.scrollToRowAtIndexPath(indexPathForLastItem, atScrollPosition: .Bottom, animated: false)


    var contentOffset = tableView.contentOffset
    contentOffset.y = tableView.contentSize.height - tableView.bounds.size.height
    tableView.setContentOffset(contentOffset, animated: false)

Run Code Online (Sandbox Code Playgroud)

    dispatch_async(dispatch_get_main_queue(), {
        // tried option 1., 2. and 3. here
    })

Run Code Online (Sandbox Code Playgroud)

至于我试图调用这些实现的地方:

  1. viewDidLoad
  2. viewWillAppear
  3. viewDidLayoutSubviews (只是第一次调用它时,我使用属性来跟踪它)
  4. viewDidAppear (即使这不会给我我想要的东西)
  5. 在我的模型上 didSet

在那些我总是打电话之前 tableView.reloadData

我不想做的事:

tableView.transform = CGAffineTransformMakeScale(1, -1)

+

cell.transform = CGAffineTransformMakeScale(1, -1)

(我假设如果你想建议这个解决方案,那是因为你知道我正在谈论的黑客.如果你不这样做,那么你就不会建议这样做,所以你不需要了解如何有用)

我不想要这个的原因之一是因为现在我无法滚动到顶部...

我注意到的问题:

  1. tableViewcontentSize(作为UIScrollView滚动时首次就出现之后的子类)的变化.是的,我的意思是contentSize,而不是contentOffset,当你滚动时它会改变不止一次.滚动整整tableView一次后,它不会再改变了.
  2. 有些人说它适用于较少的细胞(说实话,它在某些时候对我有效),所以尝试至少20项.
  3. viewWillAppear没有被召唤,但viewDidAppear确实如此.

我非常感谢任何解决方案(除了我提到的我不想要的解决方案).即使是hacky,只要他们不打破其他东西.

就像旁注一样,scrollToRowAtIndexPath...不会缩放,也就是说,如果你有2000个项目它太慢了.所以理想情况下我更喜欢可扩展的解决方案.

回答后的编辑:

  1. 在@ bsmith11的回答之后我尝试了:

    private var called = false
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        if !called {
            dispatch_async(dispatch_get_main_queue(), {
                self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.bounds.height), animated: false)
            })
            called = true
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    它没有用.

小智 4

在 中viewDidLayoutSubviews(),将.contentOffset设为tableView.bounds.height。您需要在异步块中启动此操作,以便有tableView时间加载其内容。

dispatch_async(dispatch_get_main_queue()) { self.tableView.setContentOffset(tableView.bounds.height, animated: false) }

viewDidLayoutSubviews()可以被多次调用,因此您可能希望确保上面的代码仅被调用一次。