ios - 获取将插入到 UITableView 中的行的索引

标签 ios objective-c uitableview core-data

我想做的是在 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;
    }
}

最佳答案

你走错了方向。 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 条款 - 它会自动为您重新获取,您的 View 将通过我上面粘贴的委托(delegate)方法得到通知。

关于ios - 获取将插入到 UITableView 中的行的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31935557/

相关文章:

ios - 数组和表格 View : only add new items

iphone - 我将如何在首次运行时呈现特定区域的 map View ?

ios - 在 iOS 上,setNeedsDisplay 确实不会导致 drawRect 被调用...除非 CALayer 的显示或 drawInContext 最后调用 drawRect?

iphone - 像弹出警报 View 时一样暗淡的背景

ios - 将对象传递给选择器时遇到问题

objective-c - Xcode 错误 : Expected identifier

ios - 尝试在 iOS Swift 中获取位置权限

ios - UIAppearance 更改 UITableView backgroundView 导致主线程崩溃

ios - FMDB 移动到 FMResultSet 中的第一个结果

ios - 在滚动或重新加载 tableviewcell 之前,UITableView 不显示远程图像