2015-01-26 33 views
1

我正在研究iOS應用程序的消息傳遞組件。每個消息是一排我UITableView _messageTable我嘗試下面的代碼在viewDidLoadviewWillAppearviewDidAppear(消息從後臺線程進來):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; 
} 
+0

我沒有看到你目前的作品有任何問題。你能否包含更多的代碼,特別是如何更新'_privateMessages'?這可能是一個多線程問題。 – Armin 2015-01-26 20:33:40

+0

這是一個表視圖控制器或具有表視圖的視圖控制器嗎?如果是後者,確保桌面視圖不在屏幕的底部。 – rmaddy 2015-01-26 20:36:29

+1

你是否動態地設置細胞的高度? – 2015-01-26 20:38:11

回答

2

我已確定此問題與單元格高度有關。通過將tableView.estimatedRowHeight增加到44.0,表格視圖完美滾動到底部。但是,當消息在給定單元格中超出1行時仍然存在問題。對於長度超過1行的每條消息,表格滾動會縮短几個像素。完全刪除tableView.estimatedRowHeight似乎導致類似的行爲,比如將其設置爲44.0。我想說我的原始問題已得到解答,但鑑於多線電池的可能性,我仍然不確定如何使其完美滾動。

編輯 - 解

不正確滾動的問題實際上通過去除UITableViewAutomaticDimension並手動計算heightForRowAtIndexPath高度解決。

+0

我記得我遇到過這種情況,需要仔細檢查以確保電池本身和要求它的接口之間的行高一致。 – 2015-01-26 22:01:26

+0

(你可能想要做的是將單元格高度存儲在你的dataSource中,這樣你就可以始終在'heightForRow ...'中返回一個精確的值。) – 2015-01-26 22:14:14

+0

(並且一定要實現'heightForRow'.IIRC,如果你的單元格不是全部標準高度,你需要這樣做。) – 2015-01-27 01:47:04

0

這是一個可以很好地處理自動單元高度尺寸的解決方案。這是一個很好的解決方法,但這似乎是Apple的一個漏洞。

設置_manualScrolling=NOviewDidLoad

-(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]; 
} 
相關問題