iOS - UITableView不滚动到数据源中的最后一行
我正在研究iOS应用程序的消息传递组件。每个消息是一排我UITableView _messageTable
我尝试下面的代码在viewDidLoad
,viewWillAppear
和viewDidAppear
(消息从后台线程进来):iOS - UITableView不滚动到数据源中的最后一行
dispatch_async(dispatch_get_main_queue(), ^{
[_messageTable reloadData];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomOfTable];
});
-(void)scrollToBottomOfTable {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
if (rowCount > 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
[_messageTable scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionBottom animated: YES];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _privateMessages.count;
}
此代码的工作,直到有大约20行左右。但是当有更多的消息时,它不会完全滚动到底部。是否有某种限制?如果它意味着一直滚动到底部,那么我认为视图加载延迟是可以的。最终我会实现某种消息加载上限,但我想先理解并解决此问题。
编辑
这是视图控制器内的表视图。我正在保存已发送并接收Message
对象的User
对象的数组属性(消息对话另一端的人。app.hero
是登录的用户,它继承了User
对象的形式)。没有意义的事情是,代码可以完美地处理大约20条消息。除此之外,它不会一直滚动,但我仍然可以按预期手动滚动到底部。其余的单元格配置代码是:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.estimatedRowHeight = 20.0;
tableView.rowHeight = UITableViewAutomaticDimension;
Message *message = [_privateMessages objectAtIndex:indexPath.row];
static NSString *cellId = @"messageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
cell.textLabel.numberOfLines=0;
}
return [self configureTableCell:cell forMessage:message];
}
- (UITableViewCell *)configureTableCell:(UITableViewCell *)cell forMessage:(Message *)message {
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (message.sender == app.hero) {
cell.backgroundColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentRight;
} else {
cell.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0.2 alpha:0.3];
cell.textLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
}
cell.textLabel.text = message.content;
return cell;
}
我已确定此问题与单元格高度有关。通过将tableView.estimatedRowHeight
增加到44.0,表格视图完美滚动到底部。但是,当消息在给定单元格中超出1行时仍然存在问题。对于长度超过1行的每条消息,表格滚动会缩短几个像素。完全删除tableView.estimatedRowHeight
似乎导致类似的行为,比如将其设置为44.0。我想说我的原始问题已得到解答,但鉴于多线电池的可能性,我仍然不确定如何使其完美滚动。
编辑 - 解
不正确滚动的问题实际上通过去除UITableViewAutomaticDimension
并手动计算heightForRowAtIndexPath
高度解决。
我记得我遇到过这种情况,需要仔细检查以确保电池本身和要求它的接口之间的行高一致。 – 2015-01-26 22:01:26
(你可能想要做的是将单元格高度存储在你的dataSource中,这样你就可以始终在'heightForRow ...'中返回一个精确的值。) – 2015-01-26 22:14:14
(并且一定要实现'heightForRow'.IIRC,如果你的单元格不是全部标准高度,你需要这样做。) – 2015-01-27 01:47:04
这是一个可以很好地处理自动单元高度尺寸的解决方案。这是一个很好的解决方法,但这似乎是Apple的一个漏洞。
设置_manualScrolling=NO
在viewDidLoad
。
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if (!decelerate) {
_manualScrolling = NO;
} else {
_manualScrolling = YES;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_manualScrolling = YES;
}
-(void)reloadTable {
dispatch_async(dispatch_get_main_queue(), ^{
[_messageTable reloadData];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomOfTable];
});
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (!_manualScrolling && ![self scrolledToBottom]) {
[self scrollToBottomOfTable];
}
}
-(BOOL)scrolledToBottom {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
NSArray *visibleIndices = [_messageTable indexPathsForVisibleRows];
NSIndexPath *lastVisibleIndex = [visibleIndices lastObject];
NSIndexPath *lastIndex = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
return lastVisibleIndex.row == lastIndex.row;
}
-(void)scrollToBottomOfTable {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
if (!rowCount > 0) return;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
[_messageTable scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionBottom animated: YES];
}
我没有看到你目前的作品有任何问题。你能否包含更多的代码,特别是如何更新'_privateMessages'?这可能是一个多线程问题。 – Armin 2015-01-26 20:33:40
这是一个表视图控制器或具有表视图的视图控制器吗?如果是后者,确保桌面视图不在屏幕的底部。 – rmaddy 2015-01-26 20:36:29
你是否动态地设置细胞的高度? – 2015-01-26 20:38:11