Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 奇怪的重新排序单元格动画/小故障_Ios_Core Data_Uitableview_Nsfetchedresultscontroller - Fatal编程技术网

Ios 奇怪的重新排序单元格动画/小故障

Ios 奇怪的重新排序单元格动画/小故障,ios,core-data,uitableview,nsfetchedresultscontroller,Ios,Core Data,Uitableview,Nsfetchedresultscontroller,我有一个奇怪的动画错误,我认为是基于我的“moveUp”和“moveDown”方法。我的编辑代码基于,所以这就是这些方法的起源 编辑是成功的,但是,在玩了一小会儿之后,它开始表现得非常奇怪。单元格被复制,某些单元格在按下“完成”按钮后仍保持编辑模式,即使其他单元格发生更改,但奇怪的是,如果您尝试移动仍处于编辑状态的单元格,它们只会悬停在不可编辑的单元格上。这一切都很令人困惑。我不知道这是我的MoveRowatineXpath方法中的问题,还是我在自定义方法中设置的实际移动中的问题。我在下面列出了

我有一个奇怪的动画错误,我认为是基于我的“
moveUp
”和“
moveDown
”方法。我的编辑代码基于,所以这就是这些方法的起源

编辑是成功的,但是,在玩了一小会儿之后,它开始表现得非常奇怪。单元格被复制,某些单元格在按下“完成”按钮后仍保持编辑模式,即使其他单元格发生更改,但奇怪的是,如果您尝试移动仍处于编辑状态的单元格,它们只会悬停在不可编辑的单元格上。这一切都很令人困惑。我不知道这是我的MoveRowatineXpath方法中的问题,还是我在自定义方法中设置的实际移动中的问题。我在下面列出了它的行为示例。(对不起,应用程序的背景是白色的,所以看起来代码被按下了。)

UITableViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    NSError *error = nil;

    if (![[self fetchedResultsController]performFetch:&error]) {
        NSLog(@"Error! %@", error);
        abort();
    }
}

- (IBAction)unwindToMainViewController:(UIStoryboardSegue *)unwindSegue {

}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (NSUInteger)countEvents
{
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
    NSFetchRequest *request = [[NSFetchRequest alloc] init] ;
    [request setEntity: entity];
    NSError *error = nil;
    NSUInteger count = [context countForFetchRequest:request error:&error];
    if (count == NSNotFound) {
        count = 0;
    }
    return count;
}

- (void)insertNewObject:(id)sender
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Top" inManagedObjectContext:context];

    [fetchRequest setEntity:entity];

    NSUInteger orderIdx = 1 + [self countEvents];

    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Top" inManagedObjectContext:context];

    // If appropriate, configure the new managed object.
    // Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.
    [newManagedObject setValue:[NSNumber numberWithInteger:orderIdx] forKey:@"orderIdx"];

    // Save the context.
    NSError *error = nil;
    if (![context save:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

-(NSManagedObjectContext*)managedObjectContext {

    return [(TTAppDelegate*)[[UIApplication sharedApplication]delegate]managedObjectContext];

}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender {

    if ([[segue identifier]isEqualToString:@"addTop"]) {

        UINavigationController *navigationController = segue.destinationViewController;

        AddTopViewController *addTopViewController = (AddTopViewController*) navigationController.topViewController;

        Top *addTop = [NSEntityDescription insertNewObjectForEntityForName:@"Top" inManagedObjectContext:self.managedObjectContext];

        addTopViewController.addTop = addTop;

    }

    if ([[segue identifier]isEqualToString:@"showList"]) {
        TopDetailTableViewController *topDetailTableViewController = [segue destinationViewController];

        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

        Top *selectedTop = (Top *)[self.fetchedResultsController objectAtIndexPath:indexPath];

        topDetailTableViewController.selectedTop = selectedTop;

        UITableViewCell *selectedCell = (UITableViewCell *)sender;
        topDetailTableViewController.title = selectedCell.textLabel.text;
    }

}


-(void) viewWillAppear:(BOOL)animated {

    [self.tableView reloadData];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
    return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    // Configure the cell...

    Top *top = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if (!cell) {
        cell = [[UITableViewCell alloc] init];
        cell.showsReorderControl = YES;
    }

    cell.textLabel.text = top.topName;
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
        [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

        NSError *error = nil;
        if (![context save:&error]) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)adjustOrderIdxForRow:(NSInteger)row inSection:(NSInteger)section by:(NSInteger)adjustment
{
    NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:section];
    Top *top = [[self fetchedResultsController] objectAtIndexPath:path];
    top.orderIdx = [NSNumber numberWithInteger:[top.orderIdx integerValue] + adjustment];
}

- (void)moveUp:(NSIndexPath*)fromIndexPath to:(NSIndexPath*)toIndexPath
{
    NSInteger section = fromIndexPath.section;

    Top *objectMoved = [[self fetchedResultsController] objectAtIndexPath:fromIndexPath];
    Top *firstObject = [[self fetchedResultsController] objectAtIndexPath:toIndexPath];
    NSNumber *firstOrderIdx = firstObject.orderIdx;
    for (NSInteger i = toIndexPath.row; i <= fromIndexPath.row - 1; i++) {
        [self adjustOrderIdxForRow:i inSection:section by:-1];
    }
    objectMoved.orderIdx = firstOrderIdx;
}

- (void)moveDown:(NSIndexPath*)fromIndexPath to:(NSIndexPath*)toIndexPath
{
    NSInteger section = fromIndexPath.section;

    Top *objectMoved = [[self fetchedResultsController] objectAtIndexPath:fromIndexPath];
    Top *lastObject = [[self fetchedResultsController] objectAtIndexPath:toIndexPath];
    NSNumber *lastOrderIdx = lastObject.orderIdx;
    for (NSInteger i = fromIndexPath.row + 1; i <= toIndexPath.row; i++) {
        [self adjustOrderIdxForRow:i inSection:section by:1];
    }
    objectMoved.orderIdx = lastOrderIdx;
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
    BOOL moveDown = toIndexPath.row > fromIndexPath.row;
    moveDown ? [self moveDown:fromIndexPath to:toIndexPath] : [self moveUp:fromIndexPath to:toIndexPath];
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    NSError *error = nil;
    if (![context save:&error]) {
        NSLog(@"Unresolved error when swapping objects order: %@, %@", error, [error userInfo]);
        abort();
    }
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    Top *event = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NSLog(@"Path: %@, orderIdx: %@", indexPath, event.orderIdx);
}

#pragma mark - Fetched results controller

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Top" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"orderIdx" ascending:NO];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _fetchedResultsController;
}

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)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)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:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}
-(void)viewDidLoad
{
[超级视图下载];
self.navigationItem.leftBarButtonItem=self.editButtonItem;
n错误*错误=nil;
如果(![[self-fetchedResultsController]性能检测:&错误]){
NSLog(@“Error!%@”,Error);
中止();
}
}
-(iAction)解除对InviewController的绑定:(UIStoryboardSegue*)解除绑定{
}
-(id)initWithStyle:(UITableViewStyle)样式
{
self=[super initWithStyle:style];
如果(自我){
//自定义初始化
}
回归自我;
}
-(整数)countEvents
{
NSManagedObjectContext*上下文=[self.fetchedResultsController managedObjectContext];
NSEntityDescription*实体=[[self.fetchedResultsController fetchRequest]实体];
NSFetchRequest*request=[[NSFetchRequest alloc]init];
[请求集合实体:实体];
n错误*错误=nil;
NSU整数计数=[FetchRequest的上下文计数:请求错误:&错误];
if(count==NSNotFound){
计数=0;
}
返回计数;
}
-(void)insertNewObject:(id)发送方
{
NSFetchRequest*fetchRequest=[[NSFetchRequest alloc]init];
NSManagedObjectContext*上下文=[self.fetchedResultsController managedObjectContext];
NSEntityDescription*entity=[NSEntityDescription entityForName:@“Top”inManagedObjectContext:context];
[FetchRequestSetEntity:entity];
NSUInteger orderIdx=1+[self countEvents];
NSManagedObject*newManagedObject=[NSEntityDescription insertNewObjectForEntityForName:@“Top”inManagedObjectContext:context];
//如果合适,请配置新的托管对象。
//通常您应该使用访问器方法,但是在这里使用KVC可以避免向模板添加自定义类。
[newManagedObject setValue:[NSNumber numberWithInteger:orderIdx]forKey:@“orderIdx”];
//保存上下文。
n错误*错误=nil;
如果(![上下文保存:&错误]){
//将此实现替换为适当处理错误的代码。
//abort()导致应用程序生成崩溃日志并终止。您不应该在装运应用程序中使用此函数,尽管它在开发过程中可能很有用。
NSLog(@“未解决的错误%@,%@”,错误,[error userInfo]);
中止();
}
}
-(NSManagedObjectContext*)managedObjectContext{
返回[(TTAppDelegate*)[[UIApplication sharedApplication]委托]managedObjectContext];
}
-(void)prepareForSegue:(UIStoryboardSegue*)segue发送方:(UITableViewCell*)发送方{
if([[segue identifier]IsequalString:@“addTop”]){
UINavigationController*navigationController=segue.destinationViewController;
AddTopViewController*AddTopViewController=(AddTopViewController*)navigationController.topViewController;
Top*addTop=[NSEntityDescription insertNewObjectForEntityForName:@“Top”在managedObjectContext:self.managedObjectContext中];
addTopViewController.addTop=addTop;
}
if([[segue identifier]IsequalString:@“showList”]){
TopDetailTableViewController*TopDetailTableViewController=[segue destinationViewController];
NSIndexPath*indexPath=[self.tableView indexPathForSelectedRow];
Top*selectedTop=(Top*)[self.fetchedResultsController对象索引路径:indexPath];
topDetailTableViewController.selectedTop=selectedTop;
UITableViewCell*selectedCell=(UITableViewCell*)发送方;
topDetailTableViewController.title=selectedCell.textLabel.text;
}
}
-(无效)视图将显示:(BOOL)动画{
[self.tableView重载数据];
}
-(无效)未收到记忆警告
{
[超级记忆警告];
//处置所有可以重新创建的资源。
}
#pragma标记-表视图数据源
-(NSInteger)表格视图中的节数:(UITableView*)表格视图
{
//返回节数。
返回[[self.fetchedResultsController节]计数];
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节
{
//返回节中的行数。
id sectionInfo=[self.fetchedResultsController sections][section];
返回[sectionInfo numberOfObjects];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell*cell=[tableView dequeueReusableCellWithIdentifier:@“cell”forIndexPath:indexPath];
//配置单元格。。。
Top*Top=[self.fetchedResultsController对象索引路径:indexPath];
如果(!单元格){
cell=[[UITableViewCell alloc]init];
cell.showsReorderControl=是;
}
cell.textlab.text=top.topName;
[self-configureCell:cell-atIndexPath:indexPath];
返回单元;
}
-(void)tableView:(UITableView*)tableView提交的编辑样式:(UITableViewCellEditingStyle)行的编辑样式索引路径:(NSIndexPath*)索引路径
{
如果(editingStyle==UITableViewCellEditingStyleDelete){
NSManagedObjectContext*上下文=[self.fetchedResultsController managedObjectContext];
[上下文删除对象:[self.fetchedResultsController对象索引路径:indexPath]];
NSErr
cell.clipsToBounds = YES;
[self.tableView bringSubViewToFront:cell];
[self.tableView beginUpdated];

// Drag and Drop Cell

// Update data set as needed

[self.tableView endUpdates];
[self.tableView reloadData];
-(void)controllerDidChangeContent
- (void)adjustOrderIdxForRow:(NSInteger)row inSection:(NSInteger)section by:(NSInteger)adjustment
{
    NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:section];

    Top *top = [[self fetchedResultsController] objectAtIndexPath:path];

    top.orderIdx = [NSNumber numberWithInteger:[top.orderIdx integerValue] + adjustment];

    [self.tableView reloadData];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];

    [self.tableView reloadData];
}