programing

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

newstyles 2023. 6. 3. 08:17

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

다음을 사용하여 테이블 셀 삽입/삭제 중insertRowsAtIndexPaths/deleteRowsAtIndexPaths에 싸인.beginUpdates/endUpdates저도 사용하고 있습니다.beginUpdates/endUpdates행 높이를 조정할 때.이러한 모든 작업은 기본적으로 애니메이션으로 표시됩니다.

사용할 때 애니메이션이 종료되었는지 확인하는 방법beginUpdates/endUpdates?

이건 어때요?

[CATransaction begin];

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

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

[CATransaction commit];

테이블 보기 애니메이션에서 사용하기 때문에 작동합니다.CALayer내부 애니메이션즉, 열려 있는 모든 곳에 애니메이션을 추가합니다.CATransaction열려 있지 않은 경우CATransaction가 존재하고(일반적인 경우), 암묵적으로 시작되며, 이는 현재 실행 루프의 끝에서 종료됩니다.하지만 여기서 한 것처럼 직접 시작하면, 그것은 그것을 사용할 것입니다.

스위프트 버전


CATransaction.begin()

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

tableView.beginUpdates()
tableView.endUpdates()

CATransaction.commit()

iOS 11 이상을 대상으로 하는 경우에는UITableView.performBatchUpdates(_:completion:)대신:

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

가능한 해결책은 호출하는 UITableView에서 상속하는 것일 수 있습니다.endUpdates덮어씁니다.setContentSizeMethodUITableView는 추가되거나 제거된 행과 일치하도록 내용 크기를 조정합니다.이 접근 방식은 다음과 같은 경우에도 효과가 있습니다.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;
    }
}

다음과 같이 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 하위 분류 제외).사용하기로 결정했습니다.performSelector:withObject:afterDelay:현재로는.이상적이지는 않지만, 일을 완수합니다.

업데이트: 사용할 수 있을 것 같습니다.scrollViewDidEndScrollingAnimation:이 목적을 위해 (이것은 내 구현에만 해당됩니다, 주석 참조).

사용할 수 있습니다.tableView:willDisplayCell:forRowAtIndexPath:예:

- (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];
}

그러나 테이블에 이미 있는 셀이 화면 밖에서 화면으로 이동할 때도 호출되므로 원하는 셀이 정확하게 아닐 수 있습니다.저는 그냥 모든 것을 살펴보았습니다.UITableView그리고.UIScrollView셀을 삽입한 직후 처리할 내용이 없는 것으로 나타납니다.


애니메이션이 끝난 후 호출할 메소드를 호출하는 것이 어떻습니까?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