如何正确覆盖reloadRowsAtIndexPaths:withRowAnimation?

Nic*_*ico 9 uitableview ios swift

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

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

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

Vla*_*lad 5

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

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

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

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

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

enum MyTableViewReloadAnimationType {
    case None
    case First
    case Second
    case Third
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个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)
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

self.tableView .reloadRowsAtIndexPaths([indexPath], withCustomAnimationType: MyTableViewReloadAnimationType.First)
Run Code Online (Sandbox Code Playgroud)

在自定义方法中,您需要使用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)
}
Run Code Online (Sandbox Code Playgroud)

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