मोडल व्यू कंट्रोलर - कैसे प्रदर्शित करें और खारिज करें


82

मैं कई दृश्य नियंत्रकों को दिखाने और खारिज करने के साथ समस्या को हल करने के बारे में पिछले एक सप्ताह से अपना सिर तोड़ रहा हूं। मैंने एक नमूना परियोजना बनाई है और परियोजना से सीधे कोड पेस्ट किया है। मेरे पास उनकी संबंधित .xib फ़ाइलों के साथ 3 दृश्य नियंत्रक हैं। MainViewController, VC1 और VC2। मेरे पास मुख्य दृश्य नियंत्रक पर दो बटन हैं।

- (IBAction)VC1Pressed:(UIButton *)sender
{
    VC1 *vc1 = [[VC1 alloc] initWithNibName:@"VC1" bundle:nil];
    [vc1 setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:vc1 animated:YES completion:nil];
}

यह कोई समस्या नहीं के साथ VC1 खोलता है। VC1 में, मेरे पास एक और बटन है जिसे VC2 खोलना चाहिए जबकि उसी समय VC1 को खारिज कर देना चाहिए।

- (IBAction)buttonPressedFromVC1:(UIButton *)sender
{
    VC2 *vc2 = [[VC2 alloc] initWithNibName:@"VC2" bundle:nil];
    [vc2 setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:vc2 animated:YES completion:nil];
    [self dismissViewControllerAnimated:YES completion:nil];
} // This shows a warning: Attempt to dismiss from view controller <VC1: 0x715e460> while a presentation or dismiss is in progress!


- (IBAction)buttonPressedFromVC2:(UIButton *)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
} // This is going back to VC1. 

मैं चाहता हूं कि यह मुख्य दृश्य नियंत्रक पर वापस जाए जबकि उसी समय VC1 को अच्छे के लिए मेमोरी से हटा दिया जाना चाहिए था। VC1 को केवल तब दिखाना चाहिए जब मैं मुख्य नियंत्रक पर VC1 बटन पर क्लिक करता हूं।

मुख्य दृश्य नियंत्रक पर अन्य बटन भी VC1 को सीधे वीसी 2 को प्रदर्शित करने में सक्षम होना चाहिए और वीसी 2 पर एक बटन क्लिक करने पर मुख्य नियंत्रक को वापस आना चाहिए। कोई लंबा चलने वाला कोड, लूप या कोई टाइमर नहीं है। नियंत्रकों को देखने के लिए बस नंगे हड्डी कॉल।

जवाबों:


189

यह रेखा:

[self dismissViewControllerAnimated:YES completion:nil];

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

[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];

आपके मामले में, आपको यह सुनिश्चित करने की आवश्यकता है कि सभी नियंत्रण में किया जाता है mainVC । आपको ViewController1 से MainViewController को सही संदेश भेजने के लिए एक प्रतिनिधि का उपयोग करना चाहिए, ताकि MainVC VC1 को खारिज कर सके और फिर VC2 पेश कर सके।

में VC2 VC1 @interface ऊपर अपने ज फ़ाइल में एक प्रोटोकॉल जोड़ें:

@protocol ViewController1Protocol <NSObject>

    - (void)dismissAndPresentVC2;

@end

और @interface अनुभाग में एक ही फाइल में नीचे प्रतिनिधि प्रतिनिधि रखने के लिए एक संपत्ति की घोषणा:

@property (nonatomic,weak) id <ViewController1Protocol> delegate;

VC1 .m फ़ाइल में, बर्खास्त बटन विधि को प्रतिनिधि विधि को कॉल करना चाहिए

- (IBAction)buttonPressedFromVC1:(UIButton *)sender {
    [self.delegate dissmissAndPresentVC2]
}

अब mainVC में, VC1 बनाते समय इसे VC1 के प्रतिनिधि के रूप में सेट करें:

- (IBAction)present1:(id)sender {
    ViewController1* vc = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil];
    vc.delegate = self;
    [self present:vc];
}

और प्रतिनिधि विधि को लागू करें:

- (void)dismissAndPresent2 {
    [self dismissViewControllerAnimated:NO completion:^{
        [self present2:nil];
    }];
}

present2:अपने VC2Pressed:बटन IBAction विधि के समान विधि हो सकती है । ध्यान दें कि यह पूर्णता ब्लॉक से यह सुनिश्चित करने के लिए कहा जाता है कि VC2 को तब तक प्रस्तुत नहीं किया जाता है जब तक कि VC1 को पूरी तरह से खारिज नहीं किया जाता है।

अब आप VC1-> VCMain-> VC2 से आगे बढ़ रहे हैं, इसलिए आप शायद केवल एक बदलाव को एनिमेटेड बनाना चाहेंगे।

अपडेट करें

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

Apple के व्यू कंट्रोलर प्रोग्रामिंग गाइड में उनके पास यह कहने के लिए है :

प्रस्तुत दृश्य नियंत्रक को खारिज करना

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

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

व्यवहार में, Apple की सलाह थोड़ी चरम है ... सामान्य मामलों में, आपको एक समर्पित प्रतिनिधि और विधि बनाने की आवश्यकता नहीं है, आप इस पर भरोसा कर सकते हैं [self presentingViewController] dismissViewControllerAnimated:- यह आपके जैसे मामलों में है जब आप चाहते हैं कि आपके बर्खास्तगी का रिमोट पर अन्य प्रभाव हो। जिन वस्तुओं की आपको देखभाल करने की आवश्यकता है।

यहाँ कुछ ऐसा है जिसे आप सभी प्रतिनिधि परेशानी के बिना काम करने की कल्पना कर सकते हैं ...

- (IBAction)dismiss:(id)sender {
    [[self presentingViewController] dismissViewControllerAnimated:YES 
                                                        completion:^{
        [self.presentingViewController performSelector:@selector(presentVC2:) 
                                            withObject:nil];
    }];

}

हमें खारिज करने के लिए प्रस्तुत करने वाले नियंत्रक से पूछने के बाद, हमारे पास एक पूर्ण ब्लॉक है जो VC2 को आमंत्रित करने के लिए presentingViewController में एक विधि कहता है। किसी प्रतिनिधि की जरूरत नहीं। (ब्लॉक का एक बड़ा विक्रय बिंदु यह है कि वे इन परिस्थितियों में प्रतिनिधियों की आवश्यकता को कम कर देते हैं)। हालाँकि इस मामले में कुछ चीजें हो रही हैं ...

  • VC1 में आप नहीं जानते कि mainVC विधि को लागू करता है present2- आप कठिन-से-डीबग त्रुटियों या क्रैश के साथ समाप्त हो सकते हैं। इससे बचने के लिए प्रतिनिधि आपकी मदद करते हैं।
  • एक बार जब VC1 खारिज कर दिया जाता है, तो यह वास्तव में पूर्ण ब्लॉक को निष्पादित करने के आसपास नहीं है ... या यह है? क्या Self.pretingViewController का मतलब कुछ और है? आप नहीं जानते (न ही मैं) ... एक प्रतिनिधि के साथ, आपके पास यह अनिश्चितता नहीं है।
  • जब मैं इस विधि को चलाने की कोशिश करता हूं, तो यह बिना किसी चेतावनी या त्रुटियों के साथ लटका रहता है।

तो कृपया ... प्रतिनिधिमंडल सीखने के लिए समय निकालें!

Update2

अपनी टिप्पणी में आपने VC2 के बर्खास्त बटन हैंडलर में इसका उपयोग करके इसे बनाने में कामयाबी हासिल की है:

 [self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil]; 

यह निश्चित रूप से बहुत सरल है, लेकिन यह आपको कई मुद्दों के साथ छोड़ देता है।

तंग युग्मन
आप हार्ड-वायरिंग कर रहे हैं अपने दृश्य संरचना एक साथ। उदाहरण के लिए, यदि आप mainVC से पहले एक नया viewController डालें, तो आपका आवश्यक व्यवहार टूट जाएगा (आप पहले वाले पर नेविगेट करेंगे)। VC1 में आपको #import VC2 भी देना होता है। इसलिए आपके पास बहुत अधिक अंतर-निर्भरताएं हैं, जो ओओपी / एमवीसी उद्देश्यों को तोड़ती हैं।

प्रतिनिधियों का उपयोग करते हुए, न तो VC1 और न ही VC2 को mainVC के बारे में कुछ भी जानने की जरूरत है या यह एंटीकेडेंट्स हैं, इसलिए हम सब कुछ शिथिल-युग्मित और मॉड्यूलर रखते हैं।

याद
VC1 दूर नहीं गया है, आप अभी भी इसे दो संकेत देते हैं:

  • mainVC के presentedViewController संपत्ति
  • VC2 के presentingViewController संपत्ति

आप इसे लॉग इन करके टेस्ट कर सकते हैं और वो भी सिर्फ VC2 से ऐसा करके

[self dismissViewControllerAnimated:YES completion:nil]; 

यह अभी भी काम करता है, फिर भी आपको VC1 पर वापस ले जाता है।

वह मुझे स्मृति रिसाव की तरह लगता है।

इसका सुराग आपको यहां मिल रही चेतावनी में है:

[self presentViewController:vc2 animated:YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
 // Attempt to dismiss from view controller <VC1: 0x715e460>
 // while a presentation or dismiss is in progress!

तर्क टूट जाता है, जैसा कि आप प्रस्तुत करने वाले कुलपति को खारिज करने का प्रयास कर रहे हैं जिसमें से VC2 प्रस्तुत कुलपति है। दूसरा संदेश वास्तव में निष्पादित नहीं होता है - अच्छी तरह से शायद कुछ सामान होता है, लेकिन आप अभी भी दो पॉइंटर्स के साथ एक ऑब्जेक्ट पर छोड़ दिए जाते हैं जिसे आपने सोचा था कि आपको छुटकारा मिल गया है। ( संपादित करें - मैंने इसकी जाँच कर ली है और यह इतना बुरा नहीं है, जब आप mainVC में वापस आते हैं तो दोनों वस्तुएं चली जाती हैं )

यह कहने का लंबा-चौड़ा तरीका है - कृपया, प्रतिनिधियों का उपयोग करें। यदि यह मदद करता है, तो मैंने यहां पैटर्न का एक और संक्षिप्त विवरण दिया है:
क्या एक कसौटी में नियंत्रक हमेशा खराब अभ्यास है?

अद्यतन 3
यदि आप वास्तव में प्रतिनिधियों से बचना चाहते हैं, तो यह सबसे अच्छा तरीका हो सकता है:

VC1 में:

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

लेकिन नहीं कुछ भी खारिज ... जैसा कि हमने जाना, यह वास्तव में वैसे भी नहीं होता है।

VC2 में:

[self.presentingViewController.presentingViewController 
    dismissViewControllerAnimated:YES
                       completion:nil];

हम (पता) हम VC1 ख़ारिज नहीं किया है के रूप में, हम वापस तक पहुँच सकते हैं के माध्यम से VC1 को MainVC। MainVC VC1 को खारिज करता है। क्योंकि VC1 चला गया है, इसे प्रस्तुत किया गया है VC2 इसके साथ जाता है, इसलिए आप स्वच्छ स्थिति में MainVC में वापस आ गए हैं।

यह अभी भी बहुत अधिक युग्मित है, क्योंकि VC1 को VC2 के बारे में जानने की आवश्यकता है, और VC2 को यह जानने की आवश्यकता है कि यह MainVC-> VC1 के माध्यम से आया था, लेकिन यह सबसे अच्छा है जो आप बिना स्पष्ट प्रतिनिधिमंडल के प्राप्त करेंगे।


1
जटिल मालूम पड़ता है। मैंने डॉट को फॉलो और कॉपी करने की कोशिश की, लेकिन बीच में ही हार गया। क्या इसे प्राप्त करने का कोई और तरीका है? मैं यह भी जोड़ना चाहता था कि ऐप प्रतिनिधि में, मुख्य नियंत्रक रूट व्यू कंट्रोलर के रूप में सेट है। मैं नेविगेशन नियंत्रकों का उपयोग नहीं करना चाहता, लेकिन सोच रहा था कि इसे प्राप्त करने के लिए इतना जटिल क्यों होना चाहिए। संक्षेप में, जब एप्लिकेशन शुरू होता है, मैं 2 बटन के साथ एक मुख्य दृश्य नियंत्रक दिखाता हूं। पहले बटन पर क्लिक करने से VC1 लोड होता है। VC1 पर एक बटन है और इसे क्लिक करने पर VC2 को बिना किसी त्रुटि या चेतावनी के लोड करना चाहिए, जबकि एक ही समय में VC1 को मेमोरी से खारिज कर दें।
हेमा

VC2 पर, मेरे पास एक बटन है और इसे क्लिक करने से VC2 को मेमोरी से खारिज कर देना चाहिए और नियंत्रण मुख्य नियंत्रक पर वापस जाना चाहिए और VC1 पर नहीं जाना चाहिए।
हेमा

@ हेमा, मैंने आपकी आवश्यकताओं को पूरी तरह से समझ लिया है, और आपको विश्वास दिलाता हूं कि यह करने का सही तरीका है। मैंने अपना जवाब थोड़ा और जानकारी के साथ अपडेट किया है, आशा है कि मदद मिलेगी। यदि आपने मेरे दृष्टिकोण की कोशिश की और फंस गए, तो कृपया एक नया प्रश्न उठाएं जो वास्तव में काम नहीं कर रहा है ताकि हम मदद कर सकें। आप इस प्रश्न को स्पष्टता के लिए वापस लिंक भी कर सकते हैं।
फाउंड्री

हाय वह था: आपकी जानकारी के लिए धन्यवाद। मैं एक और सूत्र (मूल धागा) पर भी बात कर रहा हूं और वहां उल्लिखित सुझावों से सिर्फ एक स्निपेट पोस्ट कर रहा हूं। मैं इस मुद्दे को खत्म करने के लिए सभी विशेषज्ञ जवाबों की कोशिश कर रहा हूं। URL यहाँ है: stackoverflow.com/questions/14840318/…
हेमा

1
@ हनी - शायद ऐसा है, लेकिन बयान 'कल्पना' छद्मकोड के एक टुकड़े के लिए एक बयानबाजी का जवाब था। जिस बिंदु को मैं बनाना चाहता था, वह चक्र जाल को बनाए रखने के बारे में नहीं है, लेकिन प्रश्नकर्ता को शिक्षित करने के लिए कि प्रतिनिधिमंडल एक मूल्यवान डिजाइन पैटर्न क्यों है (जो संयोगवश उस मुद्दे से बचता है)। मुझे लगता है कि यहां भ्रामक विवाद है - सवाल मॉडल कुलपतियों के बारे में है, लेकिन उत्तर का मूल्य ज्यादातर प्रतिनिधि प्रतिनिधि पैटर्न के अपने अन्वेषण, प्रश्न का उपयोग करते हुए, और ओपी के स्पष्ट कुंठाओं के उत्प्रेरक के रूप में निहित है। आपकी रुचि के लिए धन्यवाद (और आपके संपादन) !!
फाउंड्री

12

स्विफ्ट में उदाहरण , ऊपर फाउंड्री के स्पष्टीकरण का चित्रण और ऐप्पल का प्रलेखन:

  1. ऐप्पल के दस्तावेज़ीकरण और ऊपर फाउंड्री की व्याख्या पर आधारित (कुछ त्रुटियों को ठीक करते हुए), डेलिगेट डिज़ाइनर संस्करण का उपयोग करके presentViewController संस्करण।

ViewController.swift

import UIKit

protocol ViewControllerProtocol {
    func dismissViewController1AndPresentViewController2()
}

class ViewController: UIViewController, ViewControllerProtocol {

    @IBAction func goToViewController1BtnPressed(sender: UIButton) {
        let vc1: ViewController1 = self.storyboard?.instantiateViewControllerWithIdentifier("VC1") as ViewController1
        vc1.delegate = self
        vc1.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
        self.presentViewController(vc1, animated: true, completion: nil)
    }

    func dismissViewController1AndPresentViewController2() {
        self.dismissViewControllerAnimated(false, completion: { () -> Void in
            let vc2: ViewController2 = self.storyboard?.instantiateViewControllerWithIdentifier("VC2") as ViewController2
            self.presentViewController(vc2, animated: true, completion: nil)
        })
    }

}

ViewController1.swift

import UIKit

class ViewController1: UIViewController {

    var delegate: protocol<ViewControllerProtocol>!

    @IBAction func goToViewController2(sender: UIButton) {
        self.delegate.dismissViewController1AndPresentViewController2()
    }

}

ViewController2.swift

import UIKit

class ViewController2: UIViewController {

}
  1. ऊपर फाउंड्री की व्याख्या पर आधारित (कुछ त्रुटियों को ठीक करते हुए), डेलिगेटकंट्रोलर संस्करण को डेलिगेट डिज़ाइन पैटर्न का उपयोग करते हुए:

ViewController.swift

import UIKit

protocol ViewControllerProtocol {
    func popViewController1AndPushViewController2()
}

class ViewController: UIViewController, ViewControllerProtocol {

    @IBAction func goToViewController1BtnPressed(sender: UIButton) {
        let vc1: ViewController1 = self.storyboard?.instantiateViewControllerWithIdentifier("VC1") as ViewController1
        vc1.delegate = self
        self.navigationController?.pushViewController(vc1, animated: true)
    }

    func popViewController1AndPushViewController2() {
        self.navigationController?.popViewControllerAnimated(false)
        let vc2: ViewController2 = self.storyboard?.instantiateViewControllerWithIdentifier("VC2") as ViewController2
        self.navigationController?.pushViewController(vc2, animated: true)
    }

}

ViewController1.swift

import UIKit

class ViewController1: UIViewController {

    var delegate: protocol<ViewControllerProtocol>!

    @IBAction func goToViewController2(sender: UIButton) {
        self.delegate.popViewController1AndPushViewController2()
    }

}

ViewController2.swift

import UIKit

class ViewController2: UIViewController {

}

अपने उदाहरण ViewControllerवर्ग में mainVC सही है?
हनी

10

मुझे लगता है कि आपको iOS मोडल व्यू कंट्रोलर्स के बारे में कुछ मुख्य अवधारणाओं को गलत समझा गया है। जब आप VC1 को खारिज करते हैं, तो VC1 द्वारा किसी भी प्रस्तुत दृश्य नियंत्रक को भी खारिज कर दिया जाता है। Apple ने मोडल व्यू कंट्रोलर्स के लिए एक स्टैक्ड तरीके से प्रवाह करने का इरादा किया है - आपके मामले में VC2 को VC1 द्वारा प्रस्तुत किया गया है। जैसे ही आप VC1 से VC2 पेश करते हैं आप VC1 को खारिज कर रहे हैं, इसलिए यह कुल गड़बड़ है। आप जो चाहते हैं, उसे प्राप्त करने के लिए, बटन दबाया गया FromVC1 में VCVC के तुरंत बाद VCVC मौजूद VC2 होना चाहिए। और मुझे लगता है कि प्रतिनिधियों के बिना यह हासिल किया जा सकता है। रेखाओं के साथ कुछ:

UIViewController presentingVC = [self presentingViewController];
[self dismissViewControllerAnimated:YES completion:
 ^{
    [presentingVC presentViewController:vc2 animated:YES completion:nil];
 }];

ध्यान दें कि self.pretingViewController कुछ अन्य चर में संग्रहीत किया जाता है, क्योंकि vc1 खुद को खारिज करने के बाद, आपको इसके लिए कोई संदर्भ नहीं देना चाहिए।


1
बहुत आसन! मैं चाहता हूं कि अन्य लोग शीर्ष पोस्ट पर रुकने के बजाय आपके उत्तर को नीचे स्क्रॉल करेंगे।
रयान लोगग्रीम

ओपी के कोड में, समाप्त [self dismiss...]होने के बाद ऐसा क्यों नहीं होता [self present...]है? यह कुछ अतुल्यकालिक घटना नहीं है
हनी

1
@ वास्तव में, वर्तमान दृश्य कॉल करने वाले को कॉल करते समय कुछ अतुल्यकालिक होता है - इसीलिए इसमें एक पूर्ण हैंडलर होता है। लेकिन इसका उपयोग करते हुए भी, यदि आप प्रस्तुत दृश्य नियंत्रक को कुछ प्रस्तुत करने के बाद खारिज करते हैं, तो वह जो कुछ भी प्रस्तुत करता है वह सब कुछ खारिज हो जाता है। इसलिए ओपी वास्तव में एक और प्रस्तोता से वास्तव में व्यूकंट्रोलर पेश करना चाहता है, ताकि वह वर्तमान को खारिज कर सके
रादु सिमियोनेस्कु

लेकिन इसका उपयोग करते हुए भी, यदि आप कुछ प्रस्तुत करने के बाद प्रस्तुत करने वाले दृश्य नियंत्रक को खारिज करते हैं, तो वह जो कुछ भी प्रस्तुत करता है वह सब कुछ खारिज हो जाता है ... अहा, इसलिए कंपाइलर मूल रूप से कह रहा है "आप जो कर रहे हैं वह बेवकूफ है। आप बस अपने पिछले को पूर्ववत कर रहे हैं। कोड की पंक्ति (VC1 के रूप में मैं खुद को और जो कुछ भी मैं पेश कर रहा हूं) को खारिज कर दूंगा। क्या यह सही नहीं है?
हनी

संकलक इसके बारे में कुछ भी "नहीं" कहेगा, और इसे निष्पादित करते समय दुर्घटना नहीं होने की स्थिति भी हो सकती है, बस यह इस तरह से व्यवहार करेगा कि प्रोग्रामर उम्मीद नहीं करता है
रादु सिमियोनेस्कु

5

राडु सिमियोनेस्कु - कमाल का काम! और स्विफ्ट प्रेमियों के लिए आपका समाधान नीचे:

@IBAction func showSecondControlerAndCloseCurrentOne(sender: UIButton) {
    let secondViewController = storyboard?.instantiateViewControllerWithIdentifier("ConrollerStoryboardID") as UIViewControllerClass // change it as You need it
    var presentingVC = self.presentingViewController
    self.dismissViewControllerAnimated(false, completion: { () -> Void   in
        presentingVC!.presentViewController(secondViewController, animated: true, completion: nil)
    })
}

एक तरह से यह मुझे निराश करता है कि यह वास्तव में काम करता है .. मुझे समझ नहीं आता है कि ब्लॉक "self.pretingViewController" पर कब्जा क्यों नहीं करता है और एक मजबूत संदर्भ की आवश्यकता है, अर्थात "var presentingVC" .. वैसे भी, यह काम करता है। thx
emdog4

1

मैं यह चाहता था:

MapVC पूर्ण स्क्रीन में एक मानचित्र है।

जब मैं एक बटन दबाता हूं, तो यह मैप के ऊपर पॉपअपवीक (पूर्ण स्क्रीन में नहीं) को खोलता है।

जब मैं PopupVC में एक बटन दबाता हूं, तो यह MapVC में वापस आ जाता है, और फिर मैं viewDidAppear को निष्पादित करना चाहता हूं।

इसे मैने किया है:

MapVC.m: बटन कार्रवाई में, एक क्रमिक प्रोग्राम, और सेट प्रतिनिधि

- (void) buttonMapAction{
   PopupVC *popvc = [self.storyboard instantiateViewControllerWithIdentifier:@"popup"];
   popvc.delegate = self;
   [self presentViewController:popvc animated:YES completion:nil];
}

- (void)dismissAndPresentMap {
  [self dismissViewControllerAnimated:NO completion:^{
    NSLog(@"dismissAndPresentMap");
    //When returns of the other view I call viewDidAppear but you can call to other functions
    [self viewDidAppear:YES];
  }];
}

PopupVC.h: @interface से पहले, प्रोटोकॉल जोड़ें

@protocol PopupVCProtocol <NSObject>
- (void)dismissAndPresentMap;
@end

@interface के बाद, एक नई संपत्ति

@property (nonatomic,weak) id <PopupVCProtocol> delegate;

PopupVC.m:

- (void) buttonPopupAction{
  //jump to dismissAndPresentMap on Map view
  [self.delegate dismissAndPresentMap];
}

1

मैंने पेश करते समय UINavigationController का उपयोग करके समस्या को हल किया है। MainVC में, जब VC1 पेश करते हैं

let vc1 = VC1()
let navigationVC = UINavigationController(rootViewController: vc1)
self.present(navigationVC, animated: true, completion: nil)

VC1 में, जब मैं VC2 दिखाना चाहूंगा और VC1 को एक ही समय में (केवल एक एनीमेशन) को खारिज कर दूंगा, मेरे पास एक पुश एनीमेशन हो सकता है

let vc2 = VC2()
self.navigationController?.setViewControllers([vc2], animated: true)

और VC2 में, जब व्यू कंट्रोलर बंद होता है, हमेशा की तरह हम उपयोग कर सकते हैं:

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