UITableView beginUpdates / endUpdates'te animasyonun sona erdiği nasıl tespit edilir?


116

G / ekleme kullanarak tablo hücresini siliyorum insertRowsAtIndexPaths/deleteRowsAtIndexPathssarılmış beginUpdates/endUpdates. beginUpdates/endUpdatesRowHeight'ı ayarlarken de kullanıyorum . Tüm bu işlemler varsayılan olarak canlandırılmıştır.

Kullanırken animasyonun bittiğini nasıl tespit edebilirim beginUpdates/endUpdates?


1
Bilginize: Bu -scrollToRowAtIndexPath:atScrollPosition:animated:aynı zamanda için de geçerlidir .
Ben Lachman

Yanıtlar:


292

Peki buna ne dersin?

[CATransaction begin];

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

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

[CATransaction commit];

Bu işe yarar çünkü tableView CALayeranimasyonları dahili olarak animasyonları kullanır . Yani, animasyonları herhangi bir açık alana eklerler CATransaction. Açık CATransactionyoksa (normal durum), o zaman bir tane örtük olarak başlar ve mevcut çalışma döngüsünün sonunda sona erer. Ama eğer birine kendiniz başlarsanız, burada yapıldığı gibi, o zaman onu kullanacaktır.


7
Benim için çalışmadı. Tamamlama bloğu, animasyon devam ederken çağrılır.
mrvincenzo

2
@MrVincenzo Snippet'te completionBlockönceki beginUpdatesve beğeniyi ayarladınız mı endUpdates?
Rudolf Adamkovič

2
[CATransaction commit]önce değil sonra çağrılmalıdır [tableView endUpdates].
Rudolf Adamkovič

6
Tamamlama bloğu, bir hücre animasyonlu bir görünüm, yani UIActivityIndicatorView içeriyorsa asla çağrılmaz.
markturnip

3
Bunca zamandan sonra bunu asla bilmiyordum. Saf altın !! TableView.reloadData () 'nın gerekli kötülüğü ile öldürülen güzel bir animasyon görmekten daha kötüsü yoktur.
DogCoffee

31

Swift Versiyonu


CATransaction.begin()

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

tableView.beginUpdates()
tableView.endUpdates()

CATransaction.commit()

6

İOS 11 ve üstünü hedefliyorsanız, UITableView.performBatchUpdates(_:completion:)bunun yerine şunu kullanmalısınız :

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

5

UITableView, eklenen veya çıkarılan satırlarla eşleşecek şekilde içerik boyutunu ayarladığından, üzerinde aradığınız endUpdatesve üzerine yazdığınız UITableView'dan miras almak olası bir çözüm olabilir setContentSizeMethod. Bu yaklaşım da işe yaramalı reloadData.

Bir bildirimin ancak endUpdatesçağrıldıktan sonra gönderilmesini sağlamak için üzerine yazılabilir endUpdatesve orada bir bayrak konulabilir.

// 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;
    }
}

5

İşlemlerinizi UIView animasyon bloğunun içine şu şekilde ekleyebilirsiniz:

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

Krediler https://stackoverflow.com/a/12905114/634940 .


4
Bu kod benim için çalışmadı. Tamamlama bloğu sonradan endUpdates, ancak animasyonlar tamamlanmadan önce çağrıldı .
Tim Camber

1
Bu çalışmıyor. Bu örnek uygulanırken tablo görünümü animasyonu çalışmayı durdurdu.
Primoz990

Süreyi
uzatmayı

1

Henüz iyi bir çözüm bulamadık (UITableView alt sınıflamasının kısaltması). performSelector:withObject:afterDelay:Şimdilik kullanmaya karar verdim . İdeal değil, ama işi hallediyor.

GÜNCELLEME : Görünüşe göre scrollViewDidEndScrollingAnimation:bu amaç için kullanabilirim (bu benim uygulamama özeldir, yoruma bakınız).


1
scrollViewDidEndScrollingAnimationyalnızca yanıt olarak çağrılır setContentOffsetvescrollRectToVisible
samvermette

@samvermette Benim durumumda, beginUpdates / endUpdates çağrıldığında, UITableView her zaman animate-scroll. Ancak bu benim uygulamama özeldir, bu yüzden en iyi cevap olmadığına katılıyorum ama benim için işe yarıyor.
pixelfreak

Güncellemeleri bir UIView animasyon bloğuna dahil etmek mümkün görünüyor. Cevabımı aşağıda görebilirsiniz: stackoverflow.com/a/14305039/634940 .
Zdenek

0

Gibi kullanabilirsiniz 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];
}

Ancak bu, zaten tabloda bulunan bir hücre ekrandan ekrana geçtiğinde de çağrılacaktır, bu nedenle tam olarak aradığınız şey olmayabilir. Tüm UITableViewve UIScrollViewdelege yöntemlerine baktım ve bir hücre animasyon eklendikten hemen sonra işlenecek hiçbir şey görünmüyor.


Neden animasyon bittikten sonra çağrılmasını istediğiniz yöntemi 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];
    }
}

Teşekkürler chown. willDisplayCellİşe yarayacağını düşünme . Bunun animasyondan sonra olmasına ihtiyacım var çünkü ancak her şey düzeldikten sonra görsel bir güncelleme yapmam gerekiyor.
pixelfreak

np @pixelfreak, bunu yapmanın başka bir yolunu düşünürsem size bildiririm.
chown
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.