Programming

UITableView beginUpdates / endUpdates에서 애니메이션이 종료되었음을 감지하는 방법은 무엇입니까?

procodes 2020. 7. 22. 22:05
반응형

UITableView beginUpdates / endUpdates에서 애니메이션이 종료되었음을 감지하는 방법은 무엇입니까?


insertRowsAtIndexPaths/deleteRowsAtIndexPathswrap을 사용하여 테이블 셀을 삽입 / 삭제 하고 beginUpdates/endUpdates있습니다. beginUpdates/endUpdatesrowHeight를 조정할 때도 사용하고 있습니다. 이러한 모든 작업은 기본적으로 애니메이션입니다.

사용할 때 애니메이션이 끝났다는 것을 어떻게 알 수 beginUpdates/endUpdates있습니까?


이건 어때?

[CATransaction begin];

[CATransaction setCompletionBlock:^{
    // animation has finished
}];

[tableView beginUpdates];
// do some work
[tableView endUpdates];

[CATransaction commit];

이것은 tableView CALayer애니메이션이 내부에서 애니메이션을 사용하기 때문에 작동합니다 . 즉, 애니메이션을 모든 open에 추가합니다 CATransaction. 열린 것이 없으면 CATransaction(일반적인 경우), 현재 런 루프의 끝에서 종료됩니다. 그러나 여기서 시작하는 것처럼 자신을 시작하면 그 것을 사용합니다.


스위프트 버전


CATransaction.begin()

CATransaction.setCompletionBlock({
    do.something()
})

tableView.beginUpdates()
tableView.endUpdates()

CATransaction.commit()

UIView 애니메이션 블록에서 작업을 다음과 같이 묶을 수 있습니다.

- (void)tableView:(UITableView *)tableView performOperation:(void(^)())operation completion:(void(^)(BOOL finished))completion
{
    [UIView animateWithDuration:0.0 animations:^{

        [tableView beginUpdates];
        if (operation)
            operation();
        [tableView endUpdates];

    } completion:^(BOOL finished) {

        if (completion)
            completion(finished);
    }];
}

https://stackoverflow.com/a/12905114/634940에 대한 크레딧 .


UITableView 가 추가되거나 제거 된 행과 일치하도록 컨텐츠 크기를 조정하므로 호출 가능한 UITableView에서 상속 endUpdates하고이를 겹쳐 쓸 수 setContentSizeMethod있습니다. 이 방법은 또한 효과가 reloadData있습니다.

endUpdates호출 된 후에 만 알림을 보내려면 이를 덮어 쓰고 endUpdates플래그를 설정할 수도 있습니다.

// somewhere in header
@private BOOL endUpdatesWasCalled_;

-------------------

// in implementation file

- (void)endUpdates {
    [super endUpdates];
    endUpdatesWasCalled_ = YES;
}

- (void)setContentSize:(CGSize)contentSize {
    [super setContentSize:contentSize];

    if (endUpdatesWasCalled_) {
        [self notifyEndUpdatesFinished];
        endUpdatesWasCalled_ = NO;
    }
}

iOS 11 이상을 대상으로하는 경우 UITableView.performBatchUpdates(_:completion:)대신 다음을 사용해야 합니다.

tableView.performBatchUpdates({
    // delete some cells
    // insert some cells
}, completion: { finished in
    // animation complete
})

아직 좋은 해결책을 찾지 못했습니다 (UITableView 하위 클래스 부족). 나는 performSelector:withObject:afterDelay:지금 사용하기로 결정했습니다 . 이상적이지는 않지만 작업을 완료합니다.

UPDATE: It looks like I can use scrollViewDidEndScrollingAnimation: for this purpose (this is specific to my implementation, see comment).


You can use tableView:willDisplayCell:forRowAtIndexPath: like:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"tableView willDisplay Cell");
    cell.backgroundColor = [UIColor colorWithWhite:((indexPath.row % 2) ? 0.25 : 0) alpha:0.70];
}

But this will also get called when a cell that is already in the table moves from off the screen to on the screen so it may not be exactly what you are looking for. I just looked through all the UITableView and UIScrollView delegate methods and there doesnt appear to be anything to handle just after a cell is inserted animation.


Why not just call the method you want to be called when the animation ends after the endUpdates?

- (void)setDownloadedImage:(NSMutableDictionary *)d {
    NSIndexPath *indexPath = (NSIndexPath *)[d objectForKey:@"IndexPath"];
    [indexPathDelayed addObject:indexPath];
    if (!([table isDragging] || [table isDecelerating])) {
        [table beginUpdates];
        [table insertRowsAtIndexPaths:indexPathDelayed withRowAnimation:UITableViewRowAnimationFade];
        [table endUpdates];
        // --> Call Method Here <--
        loadingView.hidden = YES;
        [indexPathDelayed removeAllObjects];
    }
}

참고URL : https://stackoverflow.com/questions/7623771/how-to-detect-that-animation-has-ended-on-uitableview-beginupdates-endupdates

반응형