如何从底部向上填充UITableView?

是否可以颠倒tableView的顺序。 我已经搜索了很多解决方案,但所有结果都不是我想要实现的解决方案。 他们都建议使用scrollToRowAtIndexPath滚动到表的最后位置并反向填充数据。 但是,如果表内容是动态的,并且在某些情况下并非所有单元都有数据,则这不起作用。 例如,在普通的tableView中,顺序是:


标签1

标签2

标签3

滚动方向
v
V


期望的结果是:
滚动方向
^
^

标签3

标签2

标签1


在这个例子中,如果我使用scrollToRowAtIndexPath的建议方法并使用对象数组的长度,我只会从顶部获得第三个单元格。 并最终得到这样的东西:


意外结果:

标签3

标签2

标签1

滚动方向
v
V


任何帮助都会非常感谢你。

要从底部填充表,请使用以下命令:

 - (void)updateTableContentInset { NSInteger numRows = [self tableView:self.tableView numberOfRowsInSection:0]; CGFloat contentInsetTop = self.tableView.bounds.size.height; for (NSInteger i = 0; i < numRows; i++) { contentInsetTop -= [self tableView:self.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; if (contentInsetTop <= 0) { contentInsetTop = 0; break; } } self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0); } 

要反转元素的顺序,请使用:

 dataSourceArray = dataSourceArray.reverseObjectEnumerator.allObjects; 

Swift 2.2版本( 更新 ):

 func updateTableContentInset() { let numRows = tableView(self.tableView, numberOfRowsInSection: 0) var contentInsetTop = self.tableView.bounds.size.height for i in 0.. 

Swift 3.0 + / 4.0版本( 更新 ):

 func updateTableContentInset() { let numRows = tableView(self.tableView, numberOfRowsInSection: 0) var contentInsetTop = self.tableView.bounds.size.height for i in 0.. 

这是KlimczakM解决方案的精确解决方案,适用于自动调试的tableview单元(以及固定的单元)。 此解决方案还适用于节,节标题和节页脚。

Swift 3.0

 func updateTableContentInset(forTableView tv: UITableView) { let numSections = tv.numberOfSections var contentInsetTop = tv.bounds.size.height - (self.navigationBar?.frame.size.height ?? 0) for section in 0.. 

注意:

以上代码未经测试但应该有效。 只要确保你应对任何导航栏或tabbar的高度,你会没事的。 在上面的代码中我只为导航栏执行此操作!

Swift 3.01 – 其他解决方案可以是,旋转和翻转tableView。

 self.tableView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(M_PI))) self.tableView.transform = CGAffineTransform.init(translationX: -view.frame.width, y: view.frame.height) 

UITableView将行锚定到底部

简单的方法是使用像UILabel多行+自动布局。 – > UITableView应根据其内容(又称内在布局)resize。 创建tableview并设置以下基类:

 class IntrinsicTableView: UITableView { override var contentSize:CGSize { didSet { self.invalidateIntrinsicContentSize() } } override var intrinsicContentSize: CGSize { self.layoutIfNeeded() return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height) } 

}

现在将tableview引脚的左右和底部布局约束设置为父视图。 最重要的是顶部布局约束应设置为大于或等于0,此条件保证表不会高于其父视图。

此解决方案使用KVO 在内容大小更改时调整内容插入。 滚动到顶部时也会考虑内容插入,因为只需滚动到CGPointZero就会滚动到内容的顶部而不是滚动到表格的顶部。

 -(void)startObservingContentSizeChanges { [self.tableView addObserver:self forKeyPath:kKeyPathContentSize options:0 context:nil]; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if([keyPath isEqualToString:kKeyPathContentSize] && object == self.tableView) { // difference between content and table heights. +1 accounts for last row separator CGFloat height = MAX(self.tableView.frame.size.height - self.tableView.contentSize.height, 0) + 1; self.tableView.contentInset = UIEdgeInsetsMake(height, 0, 0, 0); // "scroll" to top taking inset into account [self.tableView setContentOffset:CGPointMake(0, -height) animated:NO]; } } 

不要费心自己编写代码。 为什么不使用ReverseExtension。 它非常简单,将为您提供所有必需的结果。 请关注此urlhttps://github.com/marty-suzuki/ReverseExtension

注意:每当需要添加新单元格时,请在数据源arrays的第0个索引处插入新添加的模型,因此新单元格应在底部添加。 否则它会在顶部添加单元格,你会再次感到困惑。

如果你有一个对象数组你在cellForRowAtIndexPath:显示,让我们说dataArray可以反转它,或者在cellForRowAtIndexPath:你可以做类似的事情:

 NSString *yourObject = dataArray[[dataArray count] - 1 - indexPath.row]; cell.textLabel.text = yourObject 

我假设你在dataArray中保留字符串。

我在cellForRowAt方法中做了:

 let reverseIndex = myArray.count-indexPath.row-1 let currCellData = myArray.object(at: reverseIndex) 

然后继续使用currCellData