UITableView startUpdates / endUpdates पर उस एनीमेशन का अंत कैसे हुआ?


116

में insertRowsAtIndexPaths/deleteRowsAtIndexPathsलिपटे का उपयोग करके मैं तालिका सेल को सम्मिलित / हटा रहा हूं beginUpdates/endUpdates। मैं भी beginUpdates/endUpdatesतब उपयोग कर रहा हूँ जब रोइंग को समायोजित किया जाए। ये सभी ऑपरेशन डिफ़ॉल्ट रूप से एनिमेटेड हैं।

मैं कैसे पता लगा सकता हूं कि उपयोग करते समय एनीमेशन समाप्त हो गया है beginUpdates/endUpdates?


1
FYI करें: यह भी लागू होता है -scrollToRowAtIndexPath:atScrollPosition:animated:
बेन लछमन

जवाबों:


292

इस बारे में क्या?

[CATransaction begin];

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

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

[CATransaction commit];

यह काम करता है क्योंकि tableView CALayerएनिमेशन आंतरिक रूप से एनिमेशन का उपयोग करता है । यही है, वे किसी भी खुले में एनिमेशन जोड़ते हैं CATransaction। यदि कोई खुला CATransactionमौजूद नहीं है (सामान्य मामला), तो एक अंतर्निहित है, जो वर्तमान रनअप के अंत में समाप्त हो गया है। लेकिन अगर आप खुद को शुरू करते हैं, जैसे यहां किया जाता है, तो यह उस एक का उपयोग करेगा।


7
मेरे लिए काम नहीं किया। कंप्लीशन ब्लॉक कहा जाता है जबकि एनीमेशन अभी भी चल रहा है।
mrvincenzo

2
@MrVincenzo क्या आपने completionBlockपहले beginUpdatesऔर endUpdatesस्निपेट में सेट किया था ?
रुडोल्फ एडमकोविच

2
[CATransaction commit]पहले नहीं बुलाया जाना चाहिए [tableView endUpdates]
रुडोल्फ एडमकोवि

6
यदि किसी सेल में एनिमेशन, यानी UIActivityIndicatorView के साथ एक दृश्य होता है, तो समापन ब्लॉक कभी नहीं कहा जाता है।
मार्कटर्निप

3
इस सब के बाद मुझे यह कभी पता नहीं चला। शुद्ध सोना !! तब कुछ भी बुरा नहीं होता है कि एक अच्छा एनीमेशन देखकर tableView.reloadData () की आवश्यक बुराई को मार दिया जाता है।
डॉग कॉफ़ी

31

स्विफ्ट संस्करण


CATransaction.begin()

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

tableView.beginUpdates()
tableView.endUpdates()

CATransaction.commit()

6

यदि आप iOS 11 और इसके बाद के संस्करण को लक्षित कर रहे हैं, तो आपको UITableView.performBatchUpdates(_:completion:)इसके बजाय उपयोग करना चाहिए :

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

5

एक संभव समाधान UITableView से प्राप्त किया जा सकता है जिस पर आप कॉल करते हैं endUpdatesऔर इसे अधिलेखित कर देते हैं setContentSizeMethod, क्योंकि UITableView जोड़ा या हटाए गए पंक्तियों से मिलान करने के लिए इसके सामग्री आकार को समायोजित करता है। इस दृष्टिकोण के लिए भी काम करना चाहिए 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;
    }
}

5

आप 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 पर क्रेडिट करें


4
यह कोड मेरे काम नहीं आया। समापन ब्लॉक के बाद बुलाया गया था endUpdates, लेकिन एनिमेशन पूरा होने से पहले।
टिम कैमर

1
यह काम नहीं करता है। इस नमूने को लागू करते समय टेबलव्यू एनीमेशन ने काम करना बंद कर दिया।
प्रिमोज़ 990

अवधि को लंबे समय तक बनाने की कोशिश करें (जैसे 0.3 सेकंड) - यह काम करना चाहिए (यह मेरे लिए काम किया)
emem

1

अभी तक एक अच्छा समाधान नहीं मिला है (UITableView को कम करने के लिए)। मैंने performSelector:withObject:afterDelay:अभी के लिए उपयोग करने का निर्णय लिया है । आदर्श नहीं है, लेकिन काम हो जाता है।

अद्यतन : ऐसा लगता है कि मैं scrollViewDidEndScrollingAnimation:इस उद्देश्य के लिए उपयोग कर सकता हूं (यह मेरे कार्यान्वयन के लिए विशिष्ट है, टिप्पणी देखें)।


1
scrollViewDidEndScrollingAnimationको केवल setContentOffsetscrollRectToVisible
samvermette

@samvermette खैर, मेरे मामले में, जब startUpdates / endUpdates कहा जाता है, तो UITableView हमेशा चेतन-स्क्रॉल होता है। लेकिन यह मेरे कार्यान्वयन के लिए विशिष्ट है, इसलिए मैं मानता हूं कि यह सबसे अच्छा जवाब नहीं है लेकिन यह मेरे लिए काम करता है।
पिक्सफ्रीक

ऐसा लगता है कि अपडेट को UIView एनीमेशन ब्लॉक में जोड़ना संभव है। : मेरा उत्तर bellow देखें stackoverflow.com/a/14305039/634940
जेडनेक

0

आप इस 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];
    }
}

धन्यवाद, चांस लगता है कि willDisplayCellकाम नहीं करेगा। मुझे एनीमेशन के बाद ऐसा करने की आवश्यकता है क्योंकि मुझे सब कुछ बसने के बाद ही एक दृश्य अद्यतन करने की आवश्यकता है।
पिक्सफ्रीक

np @pixelfreak, अगर मैं ऐसा करने का कोई और तरीका सोचता हूं तो मैं आपको बता दूंगा।
chown
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.