如果标题不明显,我想要的应该是简单的,因为当用户第一次看到它时,tableView
会一直向下滚动到底部(之前他看到了,没有动画)。
所以,我知道这已经回答了几次,但这些解决方案似乎都没有发挥作用。 为了给出一些背景信息,我现在使用Swift,自动布局和最新版本的iOS。
约束
我需要支持一些事情:
UITableView
位于UIScrollView
内(UIScrollView
水平滚动,UITableView
垂直滚动。UITableView
位于childViewController
,即我将其添加到主UIViewController
(由于某种原因,导致viewWillAppear
无法被调用 - {{ 1}}仍然被称为。)我将总结一下我的尝试:
至于实施:
viewDidAppear
tableView.contentOffset = CGPoint(x: 0, y: CGFloat.max
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)
至于我试图调用这些实施的地方:
dispatch_async(dispatch_get_main_queue(), {
// tried option 1., 2. and 3. here
})
viewDidLoad
viewWillAppear
(仅在第一次调用时,我使用属性进行跟踪)viewDidLayoutSubviews
(尽管这不会给我我想要的东西)viewDidAppear
在那之前,我总是打电话给didSet
我不想做什么:
tableView.reloadData
+
tableView.transform = CGAffineTransformMakeScale(1, -1)
(我假设如果您考虑建议使用此解决方案,那是因为您知道我正在谈论的黑客攻击。如果您不这样做,那么您赢了&#39建议这样做,所以你不需要了解它是如何工作的)
我不想要这个的原因之一是因为现在我无法滚动到顶部......
我注意到的问题:
cell.transform = CGAffineTransformMakeScale(1, -1)
' s tableView
(作为contentSize
子类)在您出现后第一次滚动时会发生变化。是的,我的意思是UIScrollView
,而不是contentSize
,当您滚动时,它会更改多次。在您滚动整个contentOffset
一次之后,它就不再发生变化。tableView
没有被调用,但viewWillAppear
会被调用。任何解决方案(除了我提到的我不想要的解决方案)都会非常感激。即使是hacky,只要他们不打破其他东西。
正如旁注所示,viewDidAppear
不会缩放,例如,如果你有2000件物品则太慢了。因此,理想情况下,我更喜欢可扩展的解决方案。
答案后的编辑:
在@ bsmith11的回答之后,我试过了:
scrollToRowAtIndexPath...
它没有用。
答案 0 :(得分:2)
在viewDidLayoutSubviews()
中,将.contentOffset
设置为tableView.bounds.height
。您需要在异步块中启用它,以便tableView
时间加载它的内容。
dispatch_async(dispatch_get_main_queue()) {
self.tableView.setContentOffset(tableView.bounds.height, animated: false)
}
viewDidLayoutSubviews()
可以多次调用,因此您可能希望确保上面的代码只被调用一次。
答案 1 :(得分:1)
刚试过下面的代码就行了。
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
myArray = [["Data": "1234567890", "Height": 44],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "12345678901234567890", "Height": 88],["Data": "End of Table", "Height": 132]]
let no = myArray.count-1
let lastIndex = NSIndexPath(forRow: no, inSection: 0)
table1.scrollToRowAtIndexPath(lastIndex, atScrollPosition: .Bottom, animated: true)
}
答案 2 :(得分:0)
将以下方法添加到自定义子类。
- (void)tableViewScrollToBottomAnimated:(BOOL)animated {
NSInteger numberOfRows = [_tableView numberOfRowsInSection:0];
if (numberOfRows) {
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:numberOfRows-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated];
}
}
在[self tableViewScrollToBottomAnimated:NO]
结束时致电viewDidAppear
。
一个问题是,不幸的是,它还会导致tableView:heightForRowAtIndexPath:
被调用三次。
答案 3 :(得分:0)
我遇到了完全相同的问题,在尝试了所有内容(与您相同)后,这很有用,关键是如果您使用autolayout,则必须在viewDidLayoutSubviews中编写scrollToBottom代码
将scrollToBottom初始化为true,然后执行此操作
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// Scroll table view to the last row
[self scrollToBottom];
}
-(void)scrollToBottom {
if (shouldScrollToLastRow)
{
CGPoint bottomOffset = CGPointMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height);
[self.tableView setContentOffset:bottomOffset animated:NO];
} }
这样做可以确保您几乎位于桌面底部,但可能不会处于最底层,因为当您处于最顶端时,无法知道确切的底部偏移量tableView,之后我们可以实现scrollViewDidScroll
-(void)scrollViewDidScroll: (UIScrollView*)scrollView
{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
// if you're not at bottom then scroll to bottom
if (!(scrollOffset + scrollViewHeight == scrollContentSizeHeight))
{
[self scrollToBottom];
} else {
// bottom reached now stop scrolling
shouldScrollToLastRow = false;
}
}
答案 4 :(得分:0)
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
}
}
我用我的UIScrollView尝试了这段代码。 并且有效。如果我删除dispatch_async
则无效。
Swift 3代码
private var called = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !called {
DispatchQueue.main.async(execute: {
self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.bounds.height), animated: false)})
called = true
}
}
答案 5 :(得分:0)
我认为在ViewDidLoad中调用[table setContentOffset:CGPointMake(0, CGFLOAT_MAX)]
和table.estimatedRowHeight = 50(change your value);
就是您所需要的。
答案 6 :(得分:0)
添加此代码
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if scrollToBottomOnce == false {
scrollToBottomOnce = true
if self.items.count > 0 {
self.tableView.setContentOffset(CGPoint(x: 0, y: CGFloat.greatestFiniteMagnitude), animated: false)
}
}
}