UITableView पंक्ति एनीमेशन अवधि और पूर्ण कॉलबैक


98

क्या UITableView पंक्ति एनिमेशन के लिए अवधि निर्दिष्ट करने का कोई तरीका है, या एनीमेशन पूरा होने पर कॉलबैक पाने के लिए?

एनीमेशन पूरा होने के बाद मैं स्क्रॉल संकेतक को फ्लैश करना चाहता हूं। इससे पहले फ्लैश करना कुछ भी नहीं करता है। अब तक मुझे जो वर्कअराउंड करना है, वह आधा सेकंड देरी से शुरू होता है (जो कि डिफ़ॉल्ट एनीमेशन अवधि लगती है), अर्थात:

[self.tableView insertRowsAtIndexPaths:newRows
                      withRowAnimation:UITableViewRowAnimationFade];
[self.tableView performSelector:@selector(flashScrollIndicators)
                     withObject:nil
                     afterDelay:0.5];

मैंने खुद कोशिश नहीं की है, लेकिन शायद यह ऐसा कर सकता है, कुछ इंडेक्स पाथ हैंडलिंग के साथ:- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath
Kalle

जवाबों:


3

आजकल अगर आप ऐसा करना चाहते हैं तो iOS 11 से नया फंक्शन शुरू हो रहा है :

- (void)performBatchUpdates:(void (^)(void))updates 
                 completion:(void (^)(BOOL finished))completion;

अपडेट क्लोजर में आप एक ही कोड को startUpdates () / endUpdates सेक्शन में रखते हैं। और सभी एनिमेशन के बाद पूरा किया जाता है।


यह भी खूब रही। मैंने इस पर ध्यान नहीं दिया था।
डैनियल डिकिसन

207

बस इसी के साथ आया था। यह कैसे करना है:

उद्देश्य सी

[CATransaction begin];
[tableView beginUpdates];
[CATransaction setCompletionBlock: ^{
    // Code to be executed upon completion
}];
[tableView insertRowsAtIndexPaths: indexPaths
                 withRowAnimation: UITableViewRowAnimationAutomatic];
[tableView endUpdates];
[CATransaction commit];

तीव्र

CATransaction.begin()
tableView.beginUpdates()
CATransaction.setCompletionBlock {
    // Code to be executed upon completion
}
tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
tableView.endUpdates()
CATransaction.commit()

2
फिर, यहाँ निर्दोष रूप से काम करता है। iOS6 और सभी। डिफ़ॉल्ट एनिमेशन में संपत्तियों को ओवरराइड करने के लिए यह एक उचित एसडीके-समर्थित तंत्र है। शायद आपके पास अपने CATransaction के भीतर अतिरिक्त, लंबे समय तक चलने वाले एनिमेशन हैं? वे नेस्टेड हैं, आप जानते हैं।
करवाग

1
IOS6 में मेरे लिए बहुत अच्छा काम करता है। उसके लिए धन्यवाद!
एरन

5
setAnimationDurationडालने / हटाने की अवधि को प्रभावित करने के लिए प्रतीत नहीं होता है। iOS 6
टॉम रेडमैन

2
हालांकि अवधि कैसे बदलें के लिए कोई सुझाव? CATransaction setAnimationDuration: कोई अंतर नहीं लगता है।
जेफ ग्रिम्स

5
IOS 5.1.1, 6.1, 7.0 में भी मेरे लिए ठीक काम करता है; लेकिन, अगर आपको एक नया tableView.contentSize प्राप्त करने की आवश्यकता है एनीमेशन के बाद (जैसा कि यह मेरे मामले में था), तो आपको उपयोग करना होगा [आत्म PerformSelectorOnMainThread: withObject: WaitUntilDone:]; अगले रनरूप में अपने प्रतिनिधि को बुलाने के लिए setCompletionBlock में। यदि आप अपने प्रतिनिधि को सीधे कॉल करते हैं, तो PerformSelectorOnMainThread के बिना, आपको tableView.contentSize के लिए पुराना मान मिलता है।
19

38

करवाग के ठीक उत्तर पर विस्तार करते हुए , ध्यान दें कि iOS 7 पर, UIView एनिमेशन के साथ कैटर्रांस के आसपास टेबल एनीमेशन अवधि का नियंत्रण प्रदान करता है।

[UIView beginAnimations:@"myAnimationId" context:nil];

[UIView setAnimationDuration:10.0]; // Set duration here

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    NSLog(@"Complete!");
}];

[myTable beginUpdates];
// my table changes
[myTable endUpdates];

[CATransaction commit];
[UIView commitAnimations];

UIView एनीमेशन की अवधि का iOS 6 पर कोई प्रभाव नहीं है। शायद iOS 7 टेबल एनिमेशन को UIView स्तर पर अलग तरह से लागू किया गया है।


एनीमेशन की अवधि को नजरअंदाज किया जाता है।
डस्टिन

26

यह एक उपयोगी चाल का एक नरक है! मैंने हर समय CATransaction सामान लिखने से बचने के लिए UITableView एक्सटेंशन लिखा।

import UIKit

extension UITableView {

    /// Perform a series of method calls that insert, delete, or select rows and sections of the table view.
    /// This is equivalent to a beginUpdates() / endUpdates() sequence, 
    /// with a completion closure when the animation is finished.
    /// Parameter update: the update operation to perform on the tableView.
    /// Parameter completion: the completion closure to be executed when the animation is completed.

    func performUpdate(_ update: ()->Void, completion: (()->Void)?) {

        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        // Table View update on row / section
        beginUpdates()
        update()
        endUpdates()

        CATransaction.commit()
    }

}

यह इस तरह प्रयोग किया जाता है:

// Insert in the tableView the section we just added in sections
self.tableView.performUpdate({
            self.tableView.insertSections([newSectionIndex], with: UITableViewRowAnimation.top)

        }, completion: {
            // Scroll to next section
            let nextSectionIndexPath = IndexPath(row: 0, section: newSectionIndex)
            self.tableView.scrollToRow(at: nextSectionIndexPath, at: .top, animated: true)
        })

बहुत बढ़िया जवाब! यह एक कारण है जो मुझे स्विफ्ट से प्यार है
गियान्नी कार्लो

@ GianniCarlo आप इसे ObjC में भी कर सकते हैं
CyberMew

@CyberMew हाँ, लेकिन एक श्रेणी बनाना हमेशा से ऐसा दर्द रहा है, विशेष रूप से अतिरिक्त फ़ाइलों के लंबे नामों के कारण
गियान्नी कार्लो

यह केवल ios 11 में उपलब्ध है, ios 10 में इसका उपयोग कैसे करें?
केमडो

@kemdo आप यह क्यों कहते हैं कि यह केवल iOS 11 में उपलब्ध है? यहां सब कुछ iOS 2+ है, इसके अलावा setCompletionBlockiOS 4+
Frédéric Adda

25

कम से कम iOS 7 के लिए ब्रेंट के ठीक जवाब को छोटा करते हुए , आप यह सब [UIView चेतन अवधि: देरी: विकल्प: एनिमेशन: पूरा:] कॉल में पूरी तरह से लपेट सकते हैं:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  [self.tableView beginUpdates];
  [self.tableView endUpdates];
} completion:^(BOOL finished) {
  // completion code
}];

हालाँकि, मैं EaseInOut के अलावा किसी अन्य चीज़ से डिफ़ॉल्ट एनीमेशन वक्र को ओवरराइड नहीं कर सकता।


2
जब इस तरह से एक पंक्ति सम्मिलित करते हैं, या @ ब्रेंट का रास्ता, हालांकि अवधि का सम्मान किया जाता है, UITableViewRowAnimation का सम्मान नहीं किया जाता है और हमेशा मेरे द्वारा निर्दिष्ट किए जाने पर भी, ऊपर का चेतन नीचे दिखाई देता है, उदाहरण के लिए IITableViewRowAnimationLeft। IOS 8.4 पर परीक्षण - किसी के पास कोई समाधान है?
डैनी

23

यहां करवाग के उत्तर का एक स्विफ्ट संस्करण है

    CATransaction.begin()
    tableView.beginUpdates()
    CATransaction.setCompletionBlock { () -> Void in
        // your code here
    }
    tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation: .Top)
    tableView.endUpdates()
    CATransaction.commit()

6

मेरे लिए मुझे कलेक्शन व्यू के लिए इसकी आवश्यकता थी। मैंने इसे हल करने के लिए एक सरल विस्तार किया है:

extension UICollectionView {

    func reloadSections(sections: NSIndexSet, completion: () -> Void){
        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        self.reloadSections(sections)

        CATransaction.commit()
    }

}

1

जैसा कि TableView की performBatchविधि केवल iOS 11 से शुरू होती है , आप निम्नलिखित एक्सटेंशन का उपयोग कर सकते हैं:

extension UITableView {
func performUpdates(_ updates: @escaping () -> Void, completion: @escaping (Bool) -> Void) {
        if #available(iOS 11.0, *) {
            self.performBatchUpdates({
                updates()
            }, completion: completion)
        } else {
            CATransaction.begin()
            beginUpdates()
            CATransaction.setCompletionBlock {
                completion(true)
            }
            updates()
            endUpdates()
            CATransaction.commit()
        }
    }
}

-8

आप सम्मिलित करने का प्रयास कर सकते हैं InsertRowsAtIndexPath a

- (void)beginUpdates
- (void)endUpdates

लेन-देन, उसके बाद फ्लैश करें।


ऊपर देखें करवाग का जवाब आपको "बाद में" के रूप में जो मायने रखता है, उसकी समस्या को हल करने की आवश्यकता है।
JLundell
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.