Как запустить UITableView на последней ячейке?

В приложении «Сообщения Apple», когда вы нажимаете имя корреспондента и переключаетесь на представление таблицы в разговоре (с воздушными шарами для каждого сообщения), таблица отображается прокручивается до конца. Нет анимации или чего-то еще, это просто.

Аналогично, в Tweetie 2, когда вы загружаете представление твитов, оно появляется прямо там, где вы в последний раз смотрели на него. Нет анимации, чтобы добраться туда, она просто там, как если бы ни одна из вышеперечисленных ячеек не была загружена.

Как это делают эти приложения? scrollToRowAtIndexPath:atScrollPosition:animated: ли они scrollToRowAtIndexPath:atScrollPosition:animated: где-то в controllerе таблицы? Если да, то как они узнают, что передать в atScrollPosition: И в каком методе он называется?

scrollToRowAtIndexPath должен работать.

В viewWillAppear: попробуйте следующее:

 [theTableView reloadData]; NSIndexPath* ip = [NSIndexPath indexPathForRow:rowNumberHere inSection:sectionNumberHere]; [theTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

rowNumberHere – номер строки в источнике данных, который вы хотите прокрутить.

atScrollPosition – это только одно из значений в перечислении UITableViewScrollPosition которое может определять, где на экране появится номер строки, которую вы хотите показать. Однако, в зависимости от количества строк и строки, в которую вы прокручиваете, это может не повлиять.

Ввод reloadData: исключает исключение, если данные еще не загружены в viewWillAppear: Если вы поместите scrollToRowAtIndexPath в viewDidAppear: вам не понадобится reloadData: но вы увидите, что таблица немного подскочит, что вы говорите, что не хотите.

Изменить: @Theory, попробуйте изменить код следующим образом …

 [tableView reloadData]; int lastRowNumber = [tableView numberOfRowsInSection:0] - 1; NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRowNumber inSection:0]; [tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

Обратите внимание: numberOfRowsInSection возвращает число строк, а не последнее число строк (число строк – 1).

Вы можете вызвать -scrollToRowAtIndexPath: atScrollPosition: анимировать в методе -viewWillAppear: вашего TableViewController.

atScrollPosition: позволяет вам указать, где вы хотите, чтобы ваша ячейка для rowAtIndexPath отображалась. Существует четыре варианта:

UITableViewScrollPositionTop – помещает вашу ячейку в верхнюю часть представления

UITableViewScrollPositionMiddle – центрирует вашу ячейку в представлении

UITableViewScrollPositionBottom – помещает вашу ячейку внизу

UITableViewScrollPositionNone – использование этого параметра будет располагаться в ячейке в пользовательском режиме с минимальной прокруткой / перемещением.

В трех сценариях поведение различно: –

Если ячейка уже отображается, она ничего не делает.

Если ячейка находится выше текущего вида, она прокручивает ячейку в верхней части представления.

Если ячейка находится под текущим видом, она прокручивает ячейку в нижней части представления.

Следуя вышеприведенному ответу DyingCactus, я добавил этот метод к моему controllerу:

 -(void)viewWillAppear:(BOOL)animated { [self.tableView reloadData]; NSIndexPath* ip = [NSIndexPath indexPathForRow:[self.tableView numberOfRowsInSection:0] - 1 inSection:0]; [self.tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO]; } 

И теперь это работает, именно то, что я хотел. Благодаря!

Я использую автозапуск, и ни один из ответов не работал для меня. Вот мое решение, которое наконец-то сработало:

 @property (nonatomic, assign) BOOL shouldScrollToLastRow; - (void)viewDidLoad { [super viewDidLoad]; _shouldScrollToLastRow = YES; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // Scroll table view to the last row if (_shouldScrollToLastRow) { _shouldScrollToLastRow = NO; [self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)]; } } 

Ответ @DyingCactus в Swift 3 :

  let lastRow: Int = self.tableView.numberOfRows(inSection: 0) - 1 let indexPath = IndexPath(row: lastRow, section: 0); self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) 

Проблема с методом scrollToRowAtIndexPath является медленной, и tableView требует времени для прокрутки вниз.

У меня была такая же проблема, после того, как вы все пробовали (так же, как и вы), это сработало, ключ в том, что если вы используете autolayout, инициализируете scrollToBottom true, а затем делаете это

 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // Scroll table view to the last row [self scrollToBottom]; } -(void)scrollToBottom { if (shouldScrollToLastRow) { CGPoint bottomOffset = CGPointMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height); [self.tableView setContentOffset:bottomOffset animated:NO]; } } 

сделав это, вы убедитесь, что вы почти на дне вашего стола, но, возможно, не в самом низу, поскольку его невозможно узнать точное смещение в нижней части, когда вы находитесь в верхней части таблицы, поэтому после этого мы можем реализовать scrollViewDidScroll

 -(void)scrollViewDidScroll: (UIScrollView*)scrollView { float scrollViewHeight = scrollView.frame.size.height; float scrollContentSizeHeight = scrollView.contentSize.height; float scrollOffset = scrollView.contentOffset.y; // if you're not at bottom then scroll to bottom if (!(scrollOffset + scrollViewHeight == scrollContentSizeHeight)) { [self scrollToBottom]; } else { // bottom reached now stop scrolling shouldScrollToLastRow = false; } } 

Примечание для прокрутки в нижнюю строку раздел должен быть последним, а не 0 (первый раздел):

 int lastSection = [self.myTableView numberOfSections] -1; if (lastSection < 0) return; int lastRow = [self.myTableView numberOfRowsInSection:lastSection] - 1; if (lastRow < 0) return; NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRow inSection:lastSection]; [self.myTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
 #import "ViewController.h" @interface ViewController () @end @implementation ViewController CGFloat labelWidth = 260.0f; CGFloat labelRequiredHeight = 180.0f; @synthesize tblView; @synthesize txtField; @synthesize chatData; - (void)viewDidLoad { [super viewDidLoad]; tblView.delegate = self; [self.tblView setSeparatorStyle:UITableViewCellSeparatorStyleNone]; chatData = [[NSMutableArray alloc] init]; [self registerForKeyboardNotifications]; } -(IBAction) textFieldDoneEditing : (id) sender { NSLog(@"the text content%@",txtField.text); [sender resignFirstResponder]; [txtField resignFirstResponder]; } - (IBAction)sendButton:(id)sender { if (txtField.text.length>0) { // updating the table immediately NSArray *data = [NSArray arrayWithObject:@"text"]; NSArray *objects = [NSArray arrayWithObject:txtField.text]; NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:data]; [chatData addObject:dictionary]; NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init]; NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:0]; [insertIndexPaths addObject:newPath]; [tblView beginUpdates]; [tblView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationTop]; [tblView endUpdates]; [tblView reloadData]; txtField.text = @""; [self.view endEditing:YES]; } } -(IBAction) backgroundTap:(id) sender { [self.txtField resignFirstResponder]; } -(BOOL)SendbtnShouldReturn:(UITextField *)textfield { [textfield resignFirstResponder]; return YES; } - (BOOL)textFieldShouldReturn:(UITextField *)textField { NSLog(@"the text content%@",txtField.text); [textField resignFirstResponder]; if (txtField.text.length>0) { // updating the table immediately NSArray *keys = [NSArray arrayWithObject:@"text"]; NSArray *objects = [NSArray arrayWithObject:txtField.text]; NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; [chatData addObject:dictionary]; NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init]; NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:0]; [insertIndexPaths addObject:newPath]; [tblView beginUpdates]; [tblView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationTop]; [tblView endUpdates]; [tblView reloadData]; txtField.text = @""; } return NO; } // Keyboard Functionality -(void) registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } -(void) freeKeyboardNotifications { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; } -(void) keyboardWasShown:(NSNotification*)aNotification { NSLog(@"Keyboard was shown"); NSDictionary* info = [aNotification userInfo]; // Get animation info from userInfo NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardFrame; [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame]; // Move [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:animationDuration]; [UIView setAnimationCurve:animationCurve]; NSLog(@"frame..%f..%f..%f..%f",self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height); NSLog(@"keyboard..%f..%f..%f..%f",keyboardFrame.origin.x, keyboardFrame.origin.y, keyboardFrame.size.width, keyboardFrame.size.height); [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y- keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)]; [tblView setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+ keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height-keyboardFrame.size.height)]; [tblView scrollsToTop]; [UIView commitAnimations]; } -(void) keyboardWillHide:(NSNotification*)aNotification { NSLog(@"Keyboard will hide"); NSDictionary* info = [aNotification userInfo]; // Get animation info from userInfo NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardFrame; [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame]; // Move [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:animationDuration]; [UIView setAnimationCurve:animationCurve]; [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)]; [tblView setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)]; [UIView commitAnimations]; UIEdgeInsets contentInsets = UIEdgeInsetsZero; self.tblView.contentInset = contentInsets; self.tblView.scrollIndicatorInsets = contentInsets; self.tblView.scrollEnabled=chatData; } #pragma mark UITableViewDataSource protocol methods - (void)scrollTableToBottom { int rowNumber = [self.tblView numberOfRowsInSection:1]; if (rowNumber > 0) [self.tblView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rowNumber-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [chatData count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *[email protected]"chatCell"; chatCell *cell = (chatCell *)[tableView dequeueReusableCellWithIdentifier: @"chatCellIdentifier"]; if(!cell) cell =[[chatCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; // NSUInteger row = [chatData count]-[indexPath row]-1; NSUInteger row=[indexPath row]; NSUInteger count = [chatData count]; if (row  self.tblView.frame.size.height) // { // [self.tblView scrollToRowAtIndexPath:[self. indexPathForLastMessage] // atScrollPosition:UITableViewScrollPositionBottom animated:YES]; // } //} -(void)viewWillAppear:(BOOL)animated { // [tblView reloadData]; // // int lastRowNumber = [tblView numberOfRowsInSection:0] - 1; // NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRowNumber inSection:0]; // [tblView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO]; } -(void)viewDidAppear:(BOOL)animated { //[tblView reloadData]; } - (void)reloadTableViewDataSource { [tblView reloadData]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end 
  • Как сделать ui отзывчивым все время и делать обновление фона?
  • Есть ли iPhone SDK API для твиттера?
  • Опубликовать фотографию на стене пользователя, используя Facebook iOS SDK
  • Прокрутка двумя пальцами с помощью UIScrollView
  • Проверить версию iOS во время выполнения?
  • Сравнение поплавковых и двойных типов данных в объекте C
  • Держите iphone активным во время запуска программы
  • Как resize UIModalPresentationFormSheet?
  • Изменение цвета фона в UIAlertView?
  • Программно извлекать использование памяти на iPhone
  • Как я могу заставить UITextField двигаться вверх, когда клавиатура присутствует?
  • Давайте будем гением компьютера.