2015-05-02 59 views
4

當您插入第一個UITableViewCellinsertRowsAtIndexPaths:withRowAnimation:時,它通常出現在UITableView的頂部。在Periscope app中,恰好相反 - 第一個插入的單元格是底部對齊的。隨着新的細胞被推入,舊的細胞在表格中向上移動。這是如何實現的?如何將UITableViewCell與UITableView的底部對齊?

enter image description here

+0

1)你確定這是一個'UITableView'用'UITableViewCell's後要叫什麼? 2)假設他們是,你確定第一個屏幕截圖中的'UITableView'的* top *和第二個屏幕截圖中'UITableView'的* top *是一樣的嗎? – nhgrif

+0

@nhgrif我不確定他們是如何實現它的。我知道如何通過完全不使用表達到這種效果,但使用標準表格框架將是理想的,因爲它爲您處理單元內存管理和動畫。對於兩張照片中的frame.origin.y是相同的,在注入新細胞的同時滑動整個桌面很困難,因爲動畫持續時間和細胞注入曲線不可公開訪問。 – Pwner

+0

我沒有說這很容易。 – nhgrif

回答

17

如果你感興趣,我是怎麼做的在潛望鏡iOS應用,它實際上是非常簡單的...

TL; DR;添加一個高度等於您的表格視圖框架高度的透明表格標題標題視圖。然後,在將單元格添加到表格時,只需簡單地爲表格視圖的內容偏移添加動畫。

給你的表查看標題視圖:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectZero]; 
    headerView.userInteractionEnabled = NO; // all touches within this space must go through to the video layer 

    return headerView; // empty header above chat, so messages flow in from bottom 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    return self.tableView.frame.size.height;   // empty header above chat, so messages flow in from bottom 
} 

將數據添加到您的表格(在我的情況下,消息被添加到一個數組稱爲_messages我然後調用reloadData上的UITableViewController)。然後調用此方法使單元格變爲動畫:

- (void)scrollTableToBottom 
{ 
    if (!self.isViewLoaded || _messages.count == 0) 
     return; 

    CGFloat offsetY = self.tableView.contentSize.height - self.tableView.frame.size.height + self.tableView.contentInset.bottom; 

    [UIView animateWithDuration:0.33 
      delay:0 
      options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction 
      animations:^{ 
       [self.tableView setContentOffset:CGPointMake(0, offsetY) animated:NO]; 
      } 
      completion:nil]; 
} 

希望有所幫助。我發現這是模擬錨定在底部的單元的非常便宜/簡單的方法。我知道有些人提到顛倒桌面,但對我來說這似乎很瘋狂。 :-)

+0

你好@Aaron Wasserman,感謝你發佈你的代碼。你能否提出一些淡出動畫的方法?我已經嘗試了很多解決方案,無法獲得所需的結果。 –

+0

我的每個單元都有一個視圖模型,用於跟蹤它在屏幕上顯示的時間以及開始淡出的時間。然後,一旦單元格被重用並設置了新的視圖模型,就可以計算從哪裏開始動畫。訣竅是使用可以輕鬆應用或從圖層中移除的CAAnimations。 –

+0

感謝大家分享! –

0

可以使用insertRowsAtIndexPath方法,然後得到的tableview滾動至底部。

[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.posts.count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationBottom]; 
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 

如果你想有一個在你的tableview的頂部巨大的差距,您可以設置滾動偏移量,並調整這一新的項目進入。

另一種方式,是翻轉的tableview顛倒過來,然後顛倒每一行。

0

Swift 4版本的Aaron Wasserman回答。

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
    let headerView = UIView(frame: .zero) 
    headerView.isUserInteractionEnabled = false 
    return headerView 
} 

// Added logic to avoid blank space at the top 
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    return tableView.frame.size.height - CGFloat(messages.count * cellHeight) 
} 

func scrollToBottom(animated: Bool) { 
    if isViewLoaded && messages.count > 0 { 

     let offset = tableView.contentSize.height - tableView.frame.size.height + tableView.contentInset.bottom 

     UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseOut, .allowUserInteraction], animations: { 
      self.tableView.setContentOffset(CGPoint(x: 0, y: offset), animated: animated) 
     }, completion: nil) 
    } 
} 

scrollToBottom方法需要tableView.reloadData()