Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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
Objective c UITableView上的动画重新加载数据_Objective C_Ios_Cocoa Touch_Uitableview - Fatal编程技术网

Objective c UITableView上的动画重新加载数据

Objective c UITableView上的动画重新加载数据,objective-c,ios,cocoa-touch,uitableview,Objective C,Ios,Cocoa Touch,Uitableview,您将如何在UITableView上动画-重新加载数据?数据源位于UIFetchedResultsController上,因此我无法使用–insertSections:withRowAnimation:,–deleteSections:withRowAnimation:包装在–BeginUpdate,–EndUpdate中 编辑: 我想在NSFetchedResultsControllerrefetch之后调用-reloadData。您不能设置reloadData的动画。必须使用表视图的插入…、删

您将如何在
UITableView
上动画
-重新加载数据
?数据源位于
UIFetchedResultsController
上,因此我无法使用
–insertSections:withRowAnimation:
–deleteSections:withRowAnimation:
包装在
–BeginUpdate
–EndUpdate中

编辑:
我想在
NSFetchedResultsController
refetch之后调用
-reloadData

您不能设置
reloadData
的动画。必须使用表视图的
插入…
删除…
移动…
重新加载行…
方法使其具有动画效果

使用
NSFetchedResultsController
时,这非常简单。
NSFetchedResultsControllerDelegate
的文档包含一组示例方法,您只需根据自己的代码进行调整即可:

- (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:[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)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器{
[self.tableView开始更新];
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeSection:(id)sectionInfo
atIndex:(nsInteger)ChangeType:(NSFetchedResultsChangeType)类型的节索引{
开关(类型){
案例NSFetchedResultsChangesInsert:
[self.tableView insertSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)一个对象
atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)类型
newindepath:(nsindepath*)newindepath{
UITableView*tableView=self.tableView;
开关(类型){
案例NSFetchedResultsChangesInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[tableView DeleteRowsatindExpath:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
[self-configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexath];
打破
案例NSFetchedResultsChangeMove:
[tableView DeleteRowsatindExpath:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器{
[self.tableView endUpdates];
}
我使用了分类方法

- (void)reloadData:(BOOL)animated
{
    [self reloadData];

    if (animated) {

        CATransition *animation = [CATransition animation];
        [animation setType:kCATransitionPush];
        [animation setSubtype:kCATransitionFromBottom];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [animation setFillMode:kCAFillModeBoth];
        [animation setDuration:.3];
        [[self layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"];

    }
}

可以使用以下方法制作重新加载数据的基本动画:

// Reload table with a slight animation
[UIView transitionWithView:tableViewReference 
                  duration:0.5f 
                   options:UIViewAnimationOptionTransitionCrossDissolve 
                animations:^(void) {
    [tableViewReference reloadData];
} completion:NULL];

我根据来自的解决方案创建了一个
UITableView
category方法

它应该重新加载所有表节。您可以使用
UITableViewRowAnimation
选项播放不同的动画效果

- (void)reloadData:(BOOL)animated
{
    [self reloadData];

    if (animated)
    {
         [self reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.numberOfSections)] withRowAnimation:UITableViewRowAnimationBottom];
    }
}
方法是:

   [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];

如果要使用动画重新加载整个表,只需调用以下行:

NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]);
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];
您可能需要使用:

目标-C

/* Animate the table view reload */
[UIView transitionWithView:self.tableView
                  duration:0.35f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^(void)
 {
      [self.tableView reloadData];
 }
                completion:nil];
Swift

UIView.transitionWithView(tableView,
                          duration:0.35,
                          options:.TransitionCrossDissolve,
                          animations:
{ () -> Void in
    self.tableView.reloadData()
},
                          completion: nil);
动画选项:

TransitionNone
从左到右的转换
从右到右的转换
过渡曲线上升
过渡曲线向下
过渡交叉溶解
从顶部翻转的转换
转换FlipFrombottom


Swift 5.1版本的answer@user500()


很抱歉,我没有提到在“refetch”之后需要重新加载表数据。我认为,它可以通过一些
CALayer
动画来完成,整体上
UITableView
。。。类似于复制表视图层、重新蚀刻、重新加载数据、设置层动画等功能…这是一个很好的答案,如果您需要自定义动画,这是一个很好的解决方案!我只有一件事要补充。在我的例子中,我遇到了一些问题,原因是在重新加载数据之前,TableView被全部滚动到底部,所以当动画发生时,它将所有单元格和表格的框架都搞乱了。我可以解决这个问题,确保在重新加载数据之前将tableView全部滚动到顶部:[self-scrollRectToVisible:CGRectMake(0,0,1,1)动画:否];我可以避免头部受到影响。我现在键入时,在表格标题中有一个搜索栏。整个表格都重新加载了动画,包括我正在键入的文本。我发现kCATransitionFade看起来比kCATransitionFromBottom好得多。非常好的解决方案,谢谢。小技巧:为了代码的可读性,方法签名实际上应该是
reloadDataAnimated:(BOOL)animated
在任何其他转换上,直到您开始滚动时才重新加载tableview数据。知道为什么吗?当您更新不在主流程中的表时,该表可能不会自动更新。在这些情况下,您可以使用:[[NSRunLoop currentRunLoop]runUntelDate:[NSDate dateWithTimeIntervalSinceNow:0.01];这在动画块中吗?不管怎样,试错法说它应该在过渡的完成块中。谢谢!:)美好的我们正在寻找一个干净的解决方案,这是一个为那些不想调用暴力重新加载数据。。。。
UIView.transitionWithView(tableView,
                          duration:0.35,
                          options:.TransitionCrossDissolve,
                          animations:
{ () -> Void in
    self.tableView.reloadData()
},
                          completion: nil);
func reloadData(_ animated: Bool) {
    reloadData()
    guard animated else { return }
    let animation = CATransition()
    animation.type = .push
    animation.subtype = .fromBottom
    animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
    animation.fillMode = .both
    animation.duration = 0.3
    layer.add(animation, forKey: "UITableViewReloadDataAnimationKey")
}