如何正确覆盖reloadRowsAtIndexPaths:withRowAnimation?

时间:2015-04-16 07:53:11

标签: ios uitableview swift

我想在重新加载UITableView的行时创建一个特殊的动画。问题是我不想一直使用这个动画,因为我有时会使用内置动画来重新加载行。

那我该怎么做呢?通过覆盖我自己的UITableView实现中的reloadRowsAtIndexPaths:withRowAnimation?怎么样?

或者也许在重新加载行时有更好的方法来获取自己的动画?

1 个答案:

答案 0 :(得分:5)

我认为你不应该覆盖reloadRowsAtIndexPaths:withRowAnimation。只需在UITableView的类别中实现自定义方法reloadRowsWithMyAnimationAtIndexPaths:,并在需要时使用它。

但是如果你想在UITableView的子类中覆盖这个方法,你可以这样做:

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths 
              withRowAnimation:(UITableViewRowAnimation)animation {
    if (self.useMyAnimation) 
        [self reloadRowsWithMyAnimationAtIndexPaths:indexPaths];
    else
        [super reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}

self.useMyAnimation只是一个标志(BOOL属性),指示要使用的动画。在重新加载操作之前设置此标志。

对于2个或更多customAnimations,您可以实现枚举:

enum MyTableViewReloadAnimationType {
    case None
    case First
    case Second
    case Third
}

然后创建一个MyTableViewReloadAnimationType属性(例如,reloadAnimationType)并使用switch选择合适的动画方法:

    var reloadAnimationType = MyTableViewReloadAnimationType.None

    override func reloadRowsAtIndexPaths(indexPaths: [AnyObject], withRowAnimation animation: UITableViewRowAnimation) {
        switch self.reloadAnimationType {
        case .None:
            super .reloadRowsAtIndexPaths(indexPaths, withRowAnimation:animation)
        default:
            self .reloadRowsAtIndexPaths(indexPaths, withCustomAnimationType:self.reloadAnimationType)
        }
    }

    func reloadRowsAtIndexPaths(indexPaths: [AnyObject], withCustomAnimationType animationType: MyTableViewReloadAnimationType) {
        switch animationType {
        case .First:
            self .reloadRowsWithFirstAnimationAtIndexPaths(indexPaths)
        case .Second:
            self .reloadRowsWithSecondAnimationAtIndexPaths(indexPaths)
        case .Third:
            self .reloadRowsWithThirdAnimationAtIndexPaths(indexPaths)
        }
    }

您可以直接调用自定义方法reloadRowsAtIndexPaths:withCustomAnimationType:

self.tableView .reloadRowsAtIndexPaths([indexPath], withCustomAnimationType: MyTableViewReloadAnimationType.First)

在自定义方法中,您需要使用dataSource方法获取当前单元格和新单元格:

func reloadRowsWithFirstAnimationAtIndexPaths(indexPaths: [AnyObject]) {
    for indexPath in indexPaths {
        var currentCell = self .cellForRowAtIndexPath(indexPath as! NSIndexPath)
        var newCell = self.dataSource .tableView(self, cellForRowAtIndexPath: indexPath as! NSIndexPath)
        var newCellHeight = self.delegate .tableView(self, heightForRowAtIndexPath: indexPath)
        var frame: CGRect = currentCell.frame
        frame.size.height = newCellHeight
        newCell.frame = frame
        self .replaceCellWithFirstAnimation(currentCell!, withAnotherCell: newCell);
    }
}

func replaceCellWithFirstAnimation(firstCell : UITableViewCell, withAnotherCell secondCell: UITableViewCell) {
    var cellsSuperview = firstCell.superview!
    //make this with animation
    firstCell .removeFromSuperview()
    cellsSuperview .addSubview(secondCell)
}

你需要处理newCell的高度>或者<然后是currentCell的高度。必须重新计算所有其他单元格框架。我认为可以使用beginUpdates和endUpdates方法完成。在使用单元格进行操作之前调用它们。