बर्खास्त करना


103

मैंने अभी iPhone 5 के लिए 4 इंच डिस्प्ले पर चलने के लिए अपने iOS ऐप को अपडेट करने के लिए XCode 4.5 में अपग्रेड किया है, लेकिन मुझे dismissModalViewControllerAnimated:' is deprecatedलाइन पर एक बिल्ड एरर मिल रहा है :

[self dismissModalViewControllerAnimated:NO];

मैंने एक पूर्ण हैंडलर के साथ अनुशंसित अधिभार को अपडेट करने की कोशिश की है (लेकिन इसे NULL पर सेट करें) इस तरह:

[self dismissModalViewControllerAnimated:NO completion:NULL];

लेकिन फिर यह लाइन दो त्रुटियाँ पैदा करती है:

warning: 'TabBarController' may not respond to '-presentModalViewController:animated:completion:'
Instance method '-presentModalViewController:animated:completion:' not found (return type defaults to 'id')

धन्यवाद!

जवाबों:


307

नई विधि है:

[self dismissViewControllerAnimated:NO completion:nil];

मोडल शब्द हटा दिया गया है; जैसा कि यह पेश एपीआई कॉल के लिए किया गया है:

[self presentViewController:vc animated:NO completion:nil];

2012 डब्ल्यूडब्ल्यूडीसी सत्र 236 - आईओएस वीडियो पर व्यू कंट्रोलर्स के विकास के कारणों पर चर्चा की गई । अनिवार्य रूप से, इस एपीआई द्वारा प्रस्तुत दृश्य नियंत्रक अब हमेशा मोडल नहीं होते हैं, और चूंकि वे एक पूरा हैंडलर जोड़ रहे थे, इसलिए इसका नाम बदलने का एक अच्छा समय था।

मार्क की टिप्पणी के जवाब में:

4.3 और ऊपर के सभी उपकरणों का समर्थन करने का सबसे अच्छा तरीका क्या है? नई विधि iOS4 में काम नहीं करती है, फिर भी iOS6 में पुरानी पद्धति को हटा दिया गया है।

मुझे लगता है कि यह लगभग एक अलग सवाल है, लेकिन मुझे लगता है कि यह एक उल्लेख के लायक है क्योंकि हर किसी के पास हर 3 साल में अपने सभी उपकरणों को अपग्रेड करने के लिए पैसा नहीं है, इसलिए हममें से कुछ के पास कुछ पुराने (5.0 पूर्व) डिवाइस हैं। फिर भी, जितना यह कहने के लिए मुझे दर्द होता है, आपको यह विचार करने की आवश्यकता है कि क्या यह 5.0 से नीचे लक्षित करने योग्य है। 5.0 से नीचे उपलब्ध कई नए और शांत एपीआई नहीं हैं। और Apple उन्हें लक्षित करने के लिए लगातार कठिन बना रहा है; उदाहरण के लिए armv6 का समर्थन Xcode 4.5 से गिरा दिया गया है।

5.0 से नीचे लक्षित करने के लिए (जब तक पूरा ब्लॉक शून्य है) बस काम का उपयोग करें respondsToSelector: विधि।

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [self presentViewController:test animated:YES completion:nil];
} else {
    [self presentModalViewController:test animated:YES];
}

मार्क की एक अन्य टिप्पणी के जवाब में:

यह काफी कुछ हो सकता है यदि मेरे आवेदन में स्टेटमेंट! ... मैं एक ऐसी श्रेणी बनाने के बारे में सोच रहा था, जिसने इस कोड को एनकैप्सुलेट किया हो, क्या UIViewControler पर एक श्रेणी बनाई जाएगी जो मुझे अस्वीकृत कर देगी?

और पूर्ण निर्णय से एक:

... वहाँ मैन्युअल रूप से कारण है कि एक संकलक चेतावनी प्रस्तुत नहीं करने के लिए है?

सबसे पहले, नहीं, UIViewControllerअपने आप में एक श्रेणी बनाने से आपका ऐप अस्वीकृत नहीं होगा; जब तक कि श्रेणी पद्धति को निजी एपीआई या कुछ इसी तरह का नहीं कहा जाता है।

एक श्रेणी विधि इस तरह के कोड के लिए एक बहुत अच्छी जगह है। इसके अलावा, चूंकि पदावनत एपीआई के लिए केवल एक कॉल होगी, इसलिए केवल एक कंपाइलर चेतावनी होगी।

पूर्ण निर्णय की टिप्पणी (प्रश्न) को संबोधित करने के लिए, हाँ आप संकलक चेतावनी को मैन्युअल रूप से दबा सकते हैं। यहाँ बहुत ही विषय पर SO पर एक उत्तर का लिंक दिया गया है । एक श्रेणी विधि एक संकलक चेतावनी को दबाने के लिए भी एक शानदार जगह है, क्योंकि आप केवल एक ही स्थान पर चेतावनी को दबा रहे हैं। आप निश्चित रूप से कंपाइलर विली-निली को चुप कराने के लिए नहीं जाना चाहते हैं।

अगर मुझे इसके लिए एक सरल श्रेणी विधि लिखनी थी, तो यह कुछ इस तरह हो सकती है:

@implementation UIViewController (NJ_ModalPresentation)
-(void)nj_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
    NSAssert(completion == nil, @"You called %@ with a non-nil completion. Don't do that!",NSStringFromSelector(_cmd));
    if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
        [self presentViewController:viewControllerToPresent animated:flag completion:completion];
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [self presentModalViewController:viewControllerToPresent animated:flag];
#pragma clang diagnostic pop
    }
}
@end

2
4.3 और ऊपर के सभी उपकरणों का समर्थन करने का सबसे अच्छा तरीका क्या है? नई विधि iOS4 में काम नहीं करती है, फिर भी iOS6 में पुरानी पद्धति को हटा दिया गया है। चट्टान और सख्त जगह?
मार्क

@Marc मैंने आपकी चिंता को दूर करने के लिए मेरे उत्तर को जोड़ा।
NJones

धन्यवाद। यदि मेरे आवेदन में बहुत सारे कथन हो सकते हैं! मुझे लगता है कि 'modalViewController' संपत्ति का उपयोग करते समय एक ही दृष्टिकोण काम कर सकता है। मैं एक ऐसी श्रेणी बनाने के बारे में सोच रहा था, जिसने इस कोड को एनकैप्सुलेट किया हो, क्या UIViewControler पर एक श्रेणी बनाई जाएगी जो मुझे अस्वीकृत कर देगी?
मार्क

कोड के if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){ [self presentViewController:test animated:YES completion:nil]; } else { [self presentModalViewController:test animated:YES]; }लिए मैन्युअल रूप से कारण है कि संकलक चेतावनी प्रस्तुत नहीं करने का एक तरीका है?
विलियम एंट्रीकेन

@FullDecent हाँ आप कर सकते हैं। मैंने उस पर कुछ जानकारी के साथ अपना उत्तर संपादित किया।
एनजेओन्स

6

अब आईओएस 6 और इसके बाद के संस्करण में, आप उपयोग कर सकते हैं:

[[Picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];

के बजाय:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

... और आप उपयोग कर सकते हैं:

[self presentViewController:picker animated:YES completion:nil];

के बजाय

[self presentModalViewController:picker animated:YES];    

4

[self dismissModalViewControllerAnimated:NO]; पदावनत कर दिया गया है।

[self dismissViewControllerAnimated:NO completion:nil];इसके बजाय उपयोग करें ।



3

चेतावनी अभी भी है। इससे छुटकारा पाने के लिए मैंने इसे एक चयनकर्ता में डाल दिया:

if ([self respondsToSelector:@selector(dismissModalViewControllerAnimated:)]) {
    [self performSelector:@selector(dismissModalViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES]];
} else {
    [self dismissViewControllerAnimated:YES completion:nil];
}

यह OCD जैसे लोगों को खुद से लाभान्वित करता है;)


यदि आपको कथन को स्विच करना चाहिए, क्योंकि मेरा मानना ​​है कि एक पदावनत पद्धति respondsToSelectorगलत होने का कारण नहीं बनेगी। इस प्रकार, नए dismissViewControllerAnimated:को भविष्य के अद्यतन तक कभी नहीं बुलाया जाएगा जहां वे संभवतः dismissModalViewControllerAnimated:पूरी तरह से हटा सकते हैं।
Jsdodgers

0

यहाँ पर इसी तरह का PresentViewController वर्जन है जो मैंने इस्तेमाल किया है अगर यह खुद की तरह अन्य newbies को मदद करता है:

if ([self respondsToSelector:@selector(presentModalViewController:animated:)]) {
    [self performSelector:@selector(presentModalViewController:animated:) withObject:testView afterDelay:0];
} else {
    [self presentViewController:configView animated:YES completion:nil];
}
[testView.testFrame setImage:info]; //this doesn't work for performSelector
[testView.testText setHidden:YES];

मैंने एक ViewController 'उदारतापूर्वक' का इस्तेमाल किया था और यह देखने के लिए कि यह क्या करने के लिए बुलाया गया था (सेटहेड और सेटइमेज का उपयोग करते हुए) के आधार पर मॉडल दृश्य प्राप्त करने में सक्षम था। और चीजें पहले अच्छी तरह से काम कर रही थीं, लेकिन PerformSlector 'सेट' सामान को नजरअंदाज करता है, इसलिए अंत में यह एक खराब समाधान प्रतीत होता है यदि आप कुशल होने की कोशिश करते हैं जैसे कि मैंने होने की कोशिश की ...

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