2012-11-02 60 views
6

我試圖用UITableView模仿iMessage泡泡文本行爲。爲了始終滾動到底部,我使用scrollToRowAtIndexPathviewDidLoadviewDidAppear。這是因爲當調用viewDidLoad方法時,表格尚未完全加載,所以我需要在viewDidAppear中額外滾動。這段代碼使竅門成爲可能不過,我想要的不是一個動畫滾動(設置animatedNO不解決這個問題),我希望表格始終從底部顯示,不加載表格,然後轉到最後一行。從底部加載UITableView

這可能嗎?我無法找到完全符合所需行爲的解決方案。

+0

你可以嘗試用翻轉180°表視圖,翻轉你自定義表格視圖單元格180°,因此它們看起來很正常,並顛倒了索引路徑的邏輯。你將在你的tableview的底部有0行。 – Moxy

+0

這似乎是一個可怕的很多工作。只需反轉切換第一個對象的最後一個對象的數據源,依此類推。然後你會以相反的順序顯示它。 – Martol1ni

+0

@ Martol1ni它只有2行代碼! – Moxy

回答

8

您可以避免來自viewDidLoad的調用,因爲從viewDidAppear內滾動會使第一次調用變爲冗餘。每次您返回視圖時都會調用viewDidAppear,但viewDidLoad僅在初始化視圖時調用一次。

我同意以前的建議,從用戶隱藏滾動,而不是改變UITableView加載數據的方式。我的建議是使用viewWillAppear方法中的scrollToRowAtIndexPath方法,將動畫設置爲NO。之後,如果在用戶可見表格時必須添加新行,請使用insertRowsAtIndexPaths:withRowAnimation:在表格視圖底部添加一行。一定要注意在數據模型的末尾添加數據,以便當用戶離開並返回時,他/她會回到相同的佈局。

希望這會有所幫助。

編輯: 剛剛看到你不接受以前的答案的原因,並認爲我會詳細闡述一點。我提出的解決方案需要最小的努力,避免一次又一次地調用reloadData,從而避免一次又一次地調用scrollToRowAtIndexPath方法。您只需要在viewWillAppear中對scrollToRowAtIndexPath進行一次調用即可滾動到表視圖的底部(這樣做時隱藏了來自用戶的轉換),並且不需要再次這樣做。

+0

我接受這個答案是因爲@NumanTariq是第一個指出刷新應該在'viewWillAppear'中完成的人。 – amb

+0

但之前做滾動,我們需要把reloadData方法,導致動畫眨眼效果出現。第一次如何解決進入屏幕並將數據添加到數組和載入表格並滾動到底部而沒有任何眨眼效果。 –

1

您可以將UITableView隱藏在viewDidLoad上,然後在將表格滾動到底部後立即將其更改爲可見viewDidAppear。這樣用戶將看不到滾動動畫。

0
scrollToRowAtIndexPath 

使用在tableview中的行滾動到特定位置

1

您可以通過一種無形的頁腳修復它,做計算在裏面。當頁腳被加載時,contentSize被更新。爲了讓它滾動,我檢查設置tableview的contentOffset。

我已經註釋掉了動畫部分,因爲你不需要它,但它也可以。

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{ 
    return 1; 
} 

-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section 
{ 
    if(tableView.contentOffset.y != tableView.contentSize.height - tableView.frame.size.height && automaticScroll){ 

     //[UIView animateWithDuration:0.0 animations:^{ 

      self.contentTableView.contentOffset = CGPointMake(0, tableView.contentSize.height - self.contentTableView.frame.size.height); 

     //} completion:^(BOOL finished) { 

      [tableView reloadData]; 

     //}]; 

     automaticScroll = NO; 
    } 

    UIView *emptyFooter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)]; 
    emptyFooter.backgroundColor = [UIColor clearColor]; 
    return emptyFooter; 
} 

我創建了一個BOOL自動滾動觸發滾動到底部。這應該在viewWillAppear方法中設置,或者在您加載數據並重新加載tableView時進行設置。

如果你想添加行,你還需要設置BOOL,如:

-(void)addItemButtonClicked:(id)sender 
{ 
    automaticScroll = YES; 
    //Add object to data 
    [self.contentTableView reloadData]; 
} 

如果您需要更多的幫助,請讓我知道。

4

我在我製作的RPN計算器中做了類似的事情。我有一個包含所有數字的表格視圖,當一個數字被添加到堆棧時,所有東西都會彈出一個單元格。當我加載視圖我呼籲:

[self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:NumOfStackItems - 1 inSection:0] 
         atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

在我的viewWillAppear。這樣我的表格視圖開始顯示在堆棧的底部,並且沒有看到動畫。通過將其放置在viewWillAppear中,每次我瀏覽到視圖時,它都會顯示在表格底部。

當我添加數字到堆棧中,我只是將它加入在保持所有的數字數組,然後把這樣的正確的行中的文本:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Cell initialization here... 
    NSUInteger row_num = [indexPath row]; 
    cell.rowNumber.text = [NSString stringWithFormat:@"%g", [DataArray objectAtIndex:NumberOfStackItems-row_num-1];// subtract the row number off to get the correct array index 
    return cell 
} 

我也確保每當我用新的值更新tableview我首先調用reloadData函數,然後調用上面引用的scrollToRowAtIndexPath函數,這樣我就停留在表的底部。

2

該溶液是重寫viewWillAppear並讓它滾動(非動畫)的底部:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self goToBottom]; 
} 

-(void)goToBottom 
{ 
    NSIndexPath *lastIndexPath = [self lastIndexPath]; 
    [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO]; 
} 

-(NSIndexPath *)lastIndexPath 
{ 
    NSInteger lastSectionIndex = MAX(0, [self.tableView numberOfSections] - 1); 
    NSInteger lastRowIndex = MAX(0, [self.tableView numberOfRowsInSection:lastSectionIndex] - 1); 
    return [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex]; 
} 

通過在viewWillAppear執行該用戶看到表之前將被完成。

17

這是最好的解決方案!

只是扭轉一切!

tableView.transform = CGAffineTransformMakeRotation(-M_PI); 
cell.transform = CGAffineTransformMakeRotation(M_PI); 

雨燕4.0:

tableView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi) 
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi) 

不過要小心,因爲現在headerView和footerView位置顛倒爲好。

+3

這是有史以來最好的答案!和容易! – Quetool

+0

打破滾動指標,但它確實工作:) – RolandasR

+1

這是一個hacky解決方案,如果您需要添加任何類型的滑動手勢/動作到單元格,將導致問題在路上。 –

0

只是在加載數據後更改內容嵌入,以便在高度小於父視圖時移動表視圖的內容視圖。

[self.tableView reloadData];   
[self.tableView setContentInset:UIEdgeInsetsMake(self.view.frame.size.height - self.tableView.contentSize.height < 0 ? 0 : self.view.frame.size.height - self.tableView.contentSize.height, 0, 0, 0)]; 
-1

雨燕3.0

// Rotate 
let rotate = CGAffineTransform(rotationAngle: -(CGFloat)(M_PI)) 

// Move to the left 
let translate = CGAffineTransform(scaleX: -1, y: 1) 

self.tableView.transform = rotate.concatenating(translate) 
0

雨燕3.1

tableView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) 
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) 

現金@Christos Hadjikyriacou

+1

最好這樣做'cell.contentView.transform = CGAffineTransform(rotationAngle:CGFloat(Double.pi))' – douarbou