2014-12-02 2 views
6

Моя цель - настроить разбивку на страницы с помощью PFQueryTableViewController. Я был бы доволен одним из этих решений:Пейджинг PFQueryTableViewController автоматически

  • 1, Пейджинг стола автоматически. Как и в случае, если objectsPerPage = 10tableView загружает следующие 10 объектов, когда фактическая строка - это строка 10. и так далее.

  • 2, пейджинг с «нагрузка больше ячейки» UITableViewCell. Как я вижу, это популярное решение, поэтому мне также понравится этот вариант.

На самом деле у меня нет ошибок при попытке второго решения, это просто не работает. Я добавил новую ячейку на Storyboard и создал для нее класс, и проверил AnyPic и другие связанные коды в качестве отправной точки. Как я вижу, я должен отображать ячейку LoadMoreCell, когда число строк меньше, чем objects.count. Я попробовал несколько способов, но ничего не работает, я все равно не могу показать LoadMoreCell.

Вот моя попытка:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    if (indexPath.row < self.objects.count) { 
     NSLog(@"THE NUMBER OF ACTUAL ROW %d", indexPath.row); 
     NSLog(@"cell tapped"); 

    } else { 

     // load more 
     [self loadNextPage]; 
     NSLog(@"LOAD NEXT PAGE"); 

    } 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *LoadMoreCellIdentifier = @"loadmore"; 
    LoadMoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier]; 

    if (!cell) { 
     cell = [[LoadMoreTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier]; 
     cell.selectionStyle = UITableViewCellSelectionStyleGray; 
     cell.loadMoreLabel.text = @"LOAD MORE CELLS"; 
     NSLog(@"NO CELL"); 
      } 

    return cell; 
} 

Другая часть моей реализации является последним кодом частью вопроса.

Мой первоначальный вопрос охватывает мои попытки с первым (пейджинг автоматически).

Мой первоначальный вопрос:

У меня есть рабочий PFQueryTableViewController, но я не могу настроить нумерация страниц для него. Мой план прост, я хочу загрузить следующую страницу, когда пользователь прокручивается в нижней части таблицы. Если в таблице отображается 10 элементов/страниц, я бы хотел отобразить следующий 10 элементов, когда появилась ячейка 10..

На самом деле я определить, когда пользователь достиг нижней части таблицы, а затем вызвать [self loadNextPage] для новых элементов, но приложение падает с этой ошибкой:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 10 from section 0 which only contains 10 rows before the update'

Я не очень понимаю, этот вопрос , потому что источник данных (массив) содержит более 40 объектов, которые могут быть загружены.

Вот как мне удается вызов метода (нумерация страниц включена в initWithCoder)

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView { 
    CGPoint offset = aScrollView.contentOffset; 
    CGRect bounds = aScrollView.bounds; 
    CGSize size = aScrollView.contentSize; 
    UIEdgeInsets inset = aScrollView.contentInset; 
    float y = offset.y + bounds.size.height - inset.bottom; 
    float h = size.height; 
    float reload_distance = 10; 
    if(y > h + reload_distance) { 
     NSLog(@"load more rows"); 
     [self loadNextPageInTable]; 
    } 
} 

-(void) loadNextPageInTable { 

    [self loadNextPage]; 
    NSLog(@"NEW PAGE LOADED"); 
} 

А вот установка табличное

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     self.parseClassName = @"followClass"; 
     self.pullToRefreshEnabled = YES; 
     self.paginationEnabled = YES; 
     self.objectsPerPage = 10; 
    } 
    return self; 
} 


- (PFQuery *)queryForTable { 
    if (![PFUser currentUser]) { 
     return nil; 
    } 

    PFQuery *followQuery = [PFQuery queryWithClassName:@"self.parseClassName"]; 
    [followQuery whereKey:@"followed" equalTo:[PFUser currentUser]]; 

    return query; 

} 

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    return self.objects.count; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object { 


    static NSString *CellIdentifier = @"followCell"; 
    FeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    cell.followLabel.text = object[@"username"]; 
    cell.avatar.file = object[@"image"]; 
    [cell.avatar loadInBackground]; 

    return cell; 

} 
+0

@Yan Я не уверен, что он выходит из строя на '[само loadNextPage]', потому что у меня есть 'NSLog' в 'queryForTable', который появляется в журнале после' NSLog (@ "load more rows"); '. Поэтому я думаю, что вызов 'queryForTable' вызывается. Нет, нет возможности удалить строки. Он работает, если я прокомментирую это. – rihe

+0

Можете ли вы написать больше кода. Возможно, из queryForTable для дальнейшего отладки и - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) раздел – Yan

+0

@Yan Я отредактировал свой вопрос. – rihe

ответ

3

Вот код, который работает в тестовом проекте. Я получаю ошибку, которую вы получаете, когда numberOfRowsInSection не закомментирован. Я вижу нагрузки больше ячейки, но он автоматически загружает все остальные клетки, дайте мне знать, если это помогает

#import "ParseDataTableViewController.h" 

@implementation ParseDataTableViewController 


- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     // Custom the table 

     // The className to query on 
     //self.parseClassName = @"ParseTest"; 

     // The key of the PFObject to display in the label of the default cell style 

     // The title for this table in the Navigation Controller. 
     self.title = @"Test"; 

     // Whether the built-in pull-to-refresh is enabled 
     self.pullToRefreshEnabled = YES; 

     // Whether the built-in pagination is enabled 
     self.paginationEnabled = YES; 

     // The number of objects to show per page 
     self.objectsPerPage = 15; 
    } 
    return self; 
} 




- (IBAction)nextPage:(id)sender 
{ 
    [self loadNextPageInTable]; 
} 

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView { 
    CGPoint offset = aScrollView.contentOffset; 
    CGRect bounds = aScrollView.bounds; 
    CGSize size = aScrollView.contentSize; 
    UIEdgeInsets inset = aScrollView.contentInset; 
    float y = offset.y + bounds.size.height - inset.bottom; 
    float h = size.height; 
    float reload_distance = 15; 
    if(y > h + reload_distance) { 
     NSLog(@"load more rows"); 
     [self loadNextPageInTable]; 
    } 
} 

-(void) loadNextPageInTable { 

    [self loadNextPage]; 
    NSLog(@"NEW PAGE LOADED"); 
} 


- (PFQuery *)queryForTable { 


    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Name BEGINSWITH 't'"]; 
    PFQuery *followQuery = [PFQuery queryWithClassName:@"ParseTest" predicate:predicate]; 


    return followQuery; 

} 

/*-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    return self.objects.count; 
}*/ 



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object { 


    static NSString *CellIdentifier = @"DataCell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    cell.textLabel.text = object[@"Name"]; 

    return cell; 

} 



@end 
+0

К сожалению, это не работает, я получаю ту же ошибку. Я думаю, что запрос загружает все результаты, если вы не устанавливаете предел, и в этом случае я не ограничивал число результатов. Может быть, проблема в том, что ячейки не могут загрузить следующие 25 объектов. У меня нет идеи. – rihe

+0

Что делать, если вы добавляете self.paginationEnabled = YES; который по умолчанию и комментирует весь метод (void) scrollViewDidScroll: (UIScrollView *) aScrollView, чтобы увидеть, если вы используете рабочую страницу по умолчанию – Yan

+0

Не помогает. Ничего не происходит, если я также вызываю loadNextPage, я получаю ту же ошибку. – rihe

0

Я создал демо-приложение первого решения. Здесь у вас есть Demo. Я не использовал PFQueryTableViewController (только UIKit), но я думаю, что с этим не будет никаких проблем.В этой демонстрации все данные генерируются локально и для имитации времени загрузки, я добавил таймер с интервалом 5 секунд.

Ошибка:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 10 from section 0 which only contains 10 rows before the update'

означает, что вы пытаетесь удалить элемент с indexPath.row = 10, но нет ни одного пункта на этой позиции. Строки подсчитываются от 0, так что 10-й (в данном случае последний) элемент имеет indexPath.row = 9.

Надеюсь, это поможет.

0

Я не знаком с PFQueryTableViewController, но здесь адаптированной рабочим раствором из одной из моих предыдущих проектов:

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    // totalObjectsCount - you need somehow to get this value, to stop loading next objects after you show all 
    if (self.objects.count < self.totalObjectsCount) { 
     return self.objects.count + 1; 
    } else { 
     return self.objects.count; 
    } 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object { 

    if (self.objects.count < self.totalObjectsCount 
      && indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1) { 
     LoadMoreCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LoadMoreCell" forIndexPath:indexPath]; 
     return cell; 

    } else { 
     // better if you use [dequeueReusableCellWithIdentifier: forIndexPath:] instead of dequeueReusableCellWithIdentifier 
     FeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FollowCell" forIndexPath:indexPath]; 

     cell.followLabel.text = object[@"username"]; 
     cell.avatar.file = object[@"image"]; 
     [cell.avatar loadInBackground]; 

     return cell; 
    } 
} 

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (self.objects.count < self.totalObjectsCount 
      && indexPath.row == [self tableView:tableView numberOfRowsInSection:indexPath.section] - 1) { 
     // isLoadingMoreData - BOOL value, which indicating, that you already fetching new objects, we don't wanna make same multiple requests 
     if (!self.isLoadingMoreData) { 
      // loadMoreData - function, where you load more objects 
      [self loadMoreData]; 
     } 
    } 
} 
1

В вашем создании ячейки вы не получили никакого способа для Tableview, чтобы создать новую ячейку если он уже не существует.

Создать новую ячейку, когда один не существует из механизма: извлечение из

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object { 


static NSString *CellIdentifier = @"followCell"; 
FeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
//adds new cell if one does not exist already 
if (!cell) { 
    cell = [FeedTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    //TODO: edit cell details 
} 


cell.followLabel.text = object[@"username"]; 
cell.avatar.file = object[@"image"]; 
[cell.avatar loadInBackground]; 

return cell; 
} 
+0

Получение той же ошибки. – rihe

Смежные вопросы