【问题标题】:get the index of the row that will be inserted in UITableView获取将在 UITableView 中插入的行的索引
【发布时间】:2015-08-11 07:20:56
【问题描述】:

我想要在 UITableView 中仅显示 10 个项目,这很容易使用 [fetchRequest setFetchLimit:10]; 但在插入第 11 个之后item 第一个元素不应再在 UITableView 中可见,元素总数应始终为 10 我已经对这个主题进行了很多研究,我只发现 Get Selected index of UITableView 所以我需要得到什么检查是否行的索引大于 10 删除第 9 个元素这里是所需的完整代码:

#import "ReservationHistoryTableViewController.h"
#import "CoreData.h"
#import "ReservationEntity.h"
#import "EntryCell.h"
#import "DetailedHistoryViewController.h"
@interface ReservationHistoryTableViewController () <NSFetchedResultsControllerDelegate>


@property (strong, nonatomic) NSFetchedResultsController *fetchedResultController ;

@end

@implementation ReservationHistoryTableViewController

- (IBAction)refresh:(id)sender {

    [self getAllReservationHistory];
    [sender endRefreshing];

}






- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier =  @"Cell";
    EntryCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    ReservationEntity *reservationEntry  = [self.fetchedResultController objectAtIndexPath:indexPath];
    [cell configureCellForEntry:reservationEntry];

    return cell;
}







-(NSFetchRequest *) entryListFetchRequest {
    NSFetchRequest *fetchRequest  = [NSFetchRequest fetchRequestWithEntityName:@"Reservations"];
    [fetchRequest setFetchLimit:10];
    [self.tableView reloadData];
    fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"reservationID" ascending:NO]];
    return fetchRequest;

}


// this method is used to fetch the data //
-(NSFetchedResultsController *) fetchedResultController {
    if(_fetchedResultController != nil)
        return _fetchedResultController;
    CoreData *coreDataStack = [CoreData defaultStack];
    NSFetchRequest *fechtRequest = [self entryListFetchRequest];
    _fetchedResultController = [[NSFetchedResultsController alloc] initWithFetchRequest:fechtRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    _fetchedResultController.delegate = self;
    return _fetchedResultController;

}




-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"details"])
    {
        UITableViewCell *cell = sender;
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
        UINavigationController *naviagationController = segue.destinationViewController;
        DetailedHistoryViewController *detailedHisotryViewController = (DetailedHistoryViewController *) naviagationController.topViewController;
        detailedHisotryViewController.entry = [self.fetchedResultController objectAtIndexPath:indexPath];
    }
}




-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
    switch (type) {
        case NSFetchedResultsChangeInsert:

//            NSIndexPath *selectedIndexPath = [self. indexPathForSelectedRow];



            if(newIndexPath.section > 10)
            {
                [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                [self.tableView deleteRowsAtIndexPaths:@[@(9)] withRowAnimation:UITableViewRowAnimationAutomatic];
// even i try if(newIndexPath.row) i could not reach my target // 

            }


            else
            {
                [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            }

            break;
        default:
            break;
    }
}

【问题讨论】:

    标签: ios objective-c uitableview core-data


    【解决方案1】:

    你走错了方向。 NSIndexPath 是用来识别行和节的,但你使用的是 CoreData,你不应该自己做这种类型的逻辑让你的生活复杂化。

    正确的解决方案是根据 Apple 指南实施 NSFetchedResultsController(您可以复制并粘贴):

    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
        // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
        [self.tableView beginUpdates];
    }
    
    
    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
    
        UITableView *tableView = self.tableView;
    
        switch(type) {
    
            case NSFetchedResultsChangeInsert:
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
    
            case NSFetchedResultsChangeDelete:
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
    
            case NSFetchedResultsChangeUpdate:
                [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
                break;
    
            case NSFetchedResultsChangeMove:
               [tableView deleteRowsAtIndexPaths:[NSArray
    arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
               [tableView insertRowsAtIndexPaths:[NSArray
    arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
               break;
        }
    }
    
    
    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
    
        switch(type) {
    
            case NSFetchedResultsChangeInsert:
                [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
    
            case NSFetchedResultsChangeDelete:
                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
    
    
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
        // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
        [self.tableView endUpdates];
    }
    

    为了删除你应该做的对象:

    [coreDataStack.managedObjectContext deleteObject:object];
    

    用于插入对象:

    [coreDataStack.managedObjectContext insertObject:object];
    

    您也可以只插入对象 - 如果它属于 NSFetchedResultsController NSFetchRequest 条款 - 它将自动为您重新获取,您的视图将通过我在上面粘贴的委托方法获得通知。

    【讨论】:

    • 我怎么知道tableView里面的元素个数是10?
    • NSFetchedResultsController 将采用这些。它在所有这些插入/删除操作期间保持结果同步 - 如果它应该重新获取因为插入了某些东西 - 它会自动执行此操作并通知您委托。您只需要确保您插入的对象实际上属于 NSFetchRequest 排序和限制条款 - 在您的情况下设置正确的 reservationID。
    • 我只提到了一个断点:case NSFetchedResultsChangeMove: [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];休息;我注意到这种情况从未发生过
    • 如果您不删除属于结果集的对象 - 它不会
    • 忘记告诉你,当从核心数据中获取数据时,我能够得到最后十条记录,这就是我想要的,但是当我插入一个新行并且项目是 10 时UITableView 最后一项应该被删除并应该插入新的让我们举这个例子 10 9 8 7 6 5 4 3 2 1 当插入 11 时它应该是这样的 11 10 9 8 7 6 5 4 3 2 抱歉因为我的英语不好,我想现在对你来说更清楚了,提前谢谢
    猜你喜欢
    • 2011-05-01
    • 2023-01-31
    • 1970-01-01
    • 2011-05-27
    • 2016-01-10
    • 2012-11-23
    • 2012-02-16
    • 1970-01-01
    • 2017-02-01
    相关资源
    最近更新 更多