खोज…


सेगमेंट का उपयोग करना (डेटा को आगे भेजना)

सेगमेंट का उपयोग करके वर्तमान दृश्य नियंत्रक से डेटा को अगले नए व्यू कंट्रोलर (पिछले व्यू कंट्रोलर नहीं) से पारित करने के लिए, पहले संबंधित स्टोरीबोर्ड में एक पहचानकर्ता के साथ एक सेगमेंट बनाएं। अपने वर्तमान दृश्य नियंत्रक की prepareForSegue विधि को ओवरराइड करें। विधि के अंदर आप अपने पहचानकर्ता द्वारा बनाई गई बहस के लिए जाँच करें। डेस्टिनेशन व्यू कंट्रोलर पर कास्ट करें और डाउनकास्ट व्यू कंट्रोलर पर प्रॉपर्टीज़ सेट करके उसे डेटा पास करें।

एक सेगमेंट के लिए एक पहचानकर्ता सेट करना:

एक सेग के लिए इंस्पेक्टर को अटेंड करता है

तर्क को प्रोग्रामबोर्ड पर सेट किया जा सकता है या स्टोरीबोर्ड में सेट किए गए बटन एक्शन इवेंट का उपयोग करके ctrl + को डेस्टिनेशन व्यू कंट्रोलर द्वारा ड्रैग किया जा सकता है। जब आप व्यू कंट्रोलर में सेग आइडेंटिफ़ायर का उपयोग करके प्रोग्राम से प्रोग्राम के लिए कॉल कर सकते हैं, तो:

उद्देश्य सी

- (void)showDetail {
    [self performSegueWithIdentifier:@"showDetailingSegue" sender:self];        
}

तीव्र

func showDetail() {
    self.performSegue(withIdentifier: "showDetailingSegue", sender: self)
}

आप prepareForSegue पेलोड को prepareForSegue विधि के prepareForSegue संस्करण में कॉन्फ़िगर कर सकते हैं। गंतव्य दृश्य नियंत्रक लोड होने से पहले आप आवश्यक गुण सेट कर सकते हैं।

उद्देश्य सी

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([segue.identifier isEqualToString:@"showDetailingSegue"]){
        DetailViewController *controller = (DetailViewController *)segue.destinationViewController;
        controller.isDetailingEnabled = YES;
    }
}

तीव्र

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showDetailingSegue" {
        let controller = segue.destinationViewController as! DetailViewController
        controller.isDetailingEnabled = true
    }    
}

DetailViewController दूसरे दृश्य नियंत्रक का नाम है और isDetailingEnabled उस दृश्य नियंत्रक में एक सार्वजनिक चर है।

इस पैटर्न पर विस्तार करने के लिए, आप किसी भी आवश्यक चर को शुरू करने में मदद करने के लिए, छद्म इनिशियलाइज़र के रूप में DetailViewController पर एक सार्वजनिक विधि का इलाज कर सकते हैं। यह सेल्फ डॉक्यूमेंट वैरिएबल होगा जिसे इसके सोर्स कोड के माध्यम से पढ़े बिना DetailViewController पर सेट करना होगा। यह भी एक आसान जगह है चूक डाल करने के लिए।

उद्देश्य सी

- (void)initVC:(BOOL *)isDetailingEnabled {
    self.isDetailingEnabled = isDetailingEnabled
}

तीव्र

func initVC(isDetailingEnabled: Bool) {
    self.isDetailingEnabled = isDetailingEnabled
}

डेलिगेट पैटर्न (डेटा वापस पास करना) का उपयोग करना

वर्तमान दृश्य नियंत्रक से डेटा को पिछले दृश्य नियंत्रक पर वापस भेजने के लिए, आप प्रतिनिधि पैटर्न का उपयोग कर सकते हैं।

यहाँ छवि विवरण दर्ज करें

यह उदाहरण मानता है कि आपने इंटरफ़ेस बिल्डर में एक सेगमेंट बनाया है और आपने showSecondViewController लिए showSecondViewController पहचानकर्ता सेट किया है। आउटलेट और कार्यों को निम्नलिखित कोड में नामों तक जाना चाहिए।

पहले देखें नियंत्रक

प्रथम दृश्य नियंत्रक के लिए कोड है

तीव्र

class FirstViewController: UIViewController, DataEnteredDelegate {

    @IBOutlet weak var label: UILabel!
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondViewController", let secondViewController = segue.destinationViewController as? SecondViewController  {
            secondViewController.delegate = self
        }
    }

    // required method of our custom DataEnteredDelegate protocol
    func userDidEnterInformation(info: String) {
        label.text = info
        navigationController?.popViewControllerAnimated(true)
    }
}

उद्देश्य सी

@interface FirstViewController : UIViewController <DataEnteredDelegate>
@property (weak, nonatomic) IBOutlet UILabel *label;
@end

@implementation FirstViewController
- (void)viewDidLoad {
    [super viewDidLoad];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    SecondViewController *secondViewController = segue.destinationViewController;
    secondViewController.delegate = self;

}
-(void)userDidEnterInformation:(NSString *)info {
    _label.text = info
    [self.navigationController popViewControllerAnimated:YES];
}
@end

हमारे कस्टम DataEnteredDelegate प्रोटोकॉल के उपयोग पर ध्यान दें।

दूसरा दृश्य नियंत्रक और प्रोटोकॉल

दूसरे दृश्य नियंत्रक के लिए कोड है

तीव्र

// protocol used for sending data back
protocol DataEnteredDelegate: class {
    func userDidEnterInformation(info: String)
}

class SecondViewController: UIViewController {

    // making this a weak variable so that it won't create a strong reference cycle
    weak var delegate: DataEnteredDelegate?
    
    @IBOutlet weak var textField: UITextField!

    @IBAction func sendTextBackButton(sender: AnyObject) {
        
        // call this method on whichever class implements our delegate protocol (the first view controller)
        delegate?.userDidEnterInformation(textField.text ?? "")
    }
}

उद्देश्य सी

@protocol DataEnteredDelegate <NSObject>
-(void)userDidEnterInformation:(NSString *)info;
@end

@interface SecondViewController : UIViewController 
@property (nonatomic) id <DataEnteredDelegate> delegate;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@end

@implementation SecondViewController
- (void)viewDidLoad {
    [super viewDidLoad];
}

- (IBAction) sendTextBackButton:(id)sender{
    [_delegate userDidEnterInformation:textField.text];
}
@end

ध्यान दें कि protocol व्यू कंट्रोलर क्लास के बाहर है।

डेटा का उपयोग करते हुए पीछे की तरफ सेगेट में प्रवेश करें

इसके विपरीत, जो आपको वर्तमान व्यू कंट्रोलर से डेस्टिनेशन व्यू कंट्रोलर तक डेटा "फॉरवर्ड" पास करने देता है:

(VC1) -> (VC2)

"खोलना" का उपयोग करके आप इसके विपरीत कर सकते हैं, गंतव्य से डेटा पास करें या वर्तमान दृश्य नियंत्रक से इसके वर्तमान दृश्य नियंत्रक से:

(VC1) <- (VC2)

नोट : ध्यान दें कि उपयोग करने से आप पहले डेटा पास कर सकते हैं और बाद में वर्तमान व्यू कंट्रोलर (VC2) से निपट लेंगे।

यह कैसे करना है:

सबसे पहले, आपको वर्तमान दृश्य नियंत्रक (वीसी 1) में निम्नलिखित घोषणा को जोड़ना होगा जो कि वह दृश्य नियंत्रक है जिसे हम डेटा पास करना चाहते हैं:

@IBAction func unwindToPresentingViewController(segue:UIStoryboardSegue)

महत्वपूर्ण बात यह है उपसर्ग का उपयोग करने के लिए है unwind , इस "सूचित" Xcode है कि यह एक खोलना विधि आप अच्छी तरह से स्टोरीबोर्ड में इसका इस्तेमाल करने का विकल्प दे रहा है।

बाद में आपको विधि को लागू करने की आवश्यकता होगी, यह लगभग वास्तविक सेगमेंट के समान दिखता है:

@IBAction func unwindToPresentingViewController(segue:UIStoryboardSegue)
{
    if segue.identifier == "YourCustomIdentifer"
    {
        if let VC2 = segue.sourceViewController as? VC2
        {
            //    Your custom code in here to access VC2 class member
        }

अब आपके पास 2 विकल्प हैं कि आप कॉल को सुधारे:

  1. आप "हार्ड कोड" कर सकते हैं: self.performSegueWithIdentifier("YourCustomIdentifier", sender: self) जो जब भी आप प्रदर्शन करेंगे तब आप के लिए आराम करेंगे performSegueWithIdentifier
  2. आप storyboard का उपयोग करके अपने "एक्ज़िट" ऑब्जेक्ट पर storyboard मेथड को लिंक कर सकते हैं: ctrl + बटन को ड्रैग करें जिसे आप बर्न विधि को "एग्जिट" ऑब्जेक्ट पर करना चाहते हैं:

यहाँ छवि विवरण दर्ज करें

रिलीज और आपके पास अपनी कस्टम विधि को चुनने का विकल्प होगा:

यहाँ छवि विवरण दर्ज करें

क्लोजर का उपयोग करके डेटा पास करना (डेटा वापस पास करना)

डेलिवेट पैटर्न का उपयोग करने के बजाय, जो कि UIViewController वर्ग के विभिन्न भाग में कार्यान्वयन को विभाजित करता है, आप डेटा को वापस और आगे पास करने के लिए closures का भी उपयोग कर सकते हैं। यह मानकर कि आप UIStoryboardSegue का उपयोग कर रहे हैं, prepareForSegue तरीके में आप आसानी से एक कदम में नए नियंत्रक सेटअप कर सकते हैं

final class DestinationViewController: UIViewController {
    var onCompletion: ((success: Bool) -> ())?

    @IBAction func someButtonTapped(sender: AnyObject?) {
        onCompletion?(success: true)
    }
}

final class MyViewController: UIViewController {
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
        guard let destinationController = segue.destinationViewController as? DestinationViewController else { return }
    
        destinationController.onCompletion = { success in
            // this will be executed when `someButtonTapped(_:)` will be called
            print(success)
        }
    }
}

यह उपयोग का एक उदाहरण है और स्विफ्ट पर उपयोग करना बेहतर है, उद्देश्य-सी ब्लॉक का सिंटैक्स कोड को अधिक पठनीय बनाने के लिए इतना आसान नहीं है

कॉलबैक क्लोजर (ब्लॉक) पासिंग डेटा का उपयोग करना

यह विषय आईओएस विकास में एक शास्त्रीय मुद्दा है, और इसका समाधान अन्य उदाहरणों में पहले से ही दिखाया गया है। इस उदाहरण में, मैं एक और दैनिक आम उपयोग दिखाऊंगा: इस पृष्ठ पर delegate pattern उदाहरण को कॉलबैक closure में closure करके डेटा पास करना!

delegate pattern विधि से बेहतर एक बात यह है कि दो अलग-अलग स्थानों में कोड सेट करने के बजाय कोड को विभाजित करें (इस पृष्ठ पर प्रतिनिधि उदाहरण देखें, prepareForSegue , userDidEnterInformation ) बल्कि उन्हें एक साथ इकट्ठा करना (केवल prepareForSegue , मैं इसे दिखाऊंगा)

दूसरा दृश्य नियंत्रक से प्रारंभ करें

हमें यह पता लगाना चाहिए कि कॉलबैक का उपयोग कैसे करना है, तो क्या हम इसे लिख सकते हैं, यही कारण है कि हम दूसरे व्यू कंट्रोलर से शुरू करते हैं, क्योंकि हम कॉलबैक का उपयोग करते हैं: जब हमें नया टेक्स्ट इनपुट मिलता है, तो हम कॉलबैक के पैरामीटर को माध्यम के रूप में उपयोग करते हुए , कॉलबैक कहते हैं। पहले ViewController पर डेटा पास करने के लिए, ध्यान दें कि मैंने कॉलबैक के पैरामीटर का उपयोग करते हुए कहा था, यह बहुत महत्वपूर्ण है, नौसिखिए (जैसा कि मैं था) हमेशा इसे अनदेखा करते हैं और पता नहीं है कि कॉलबैक क्लोजर को ठीक से लिखना कहां शुरू करना है

तो इस मामले में, हम जानते हैं कि हमारा कॉलबैक केवल एक पैरामीटर लेता है: पाठ और उसका प्रकार String , आइए इसे घोषित करें और इसे संपत्ति बनाएं क्योंकि हमें अपने पहले दृश्य नियंत्रक से आबादी की आवश्यकता है

मैं सिर्फ सभी delegate भाग की टिप्पणी करता हूं और तुलना करने के लिए रखता हूं

class SecondViewController: UIViewController {

    //weak var delegate: DataEnteredDelegate? = nil
    var callback: ((String?)->())?
    
    @IBOutlet weak var textField: UITextField!

    @IBAction func sendTextBackButton(sender: AnyObject) {
        
        //delegate?.userDidEnterInformation(textField.text!)
        callback?(input.text)
        
        self.navigationController?.popViewControllerAnimated(true)
    }
}

पहला दृश्य नियंत्रक समाप्त करें

आपको बस कॉलबैक क्लोजर पास करना है, और हम कर रहे हैं, क्लोजर हमारे लिए भविष्य का काम करेगा क्योंकि हम पहले ही इसे दूसरे व्यू कंट्रोलर में सेट कर चुके हैं

यह देखें कि delegate pattern कोड की तुलना में यह हमारे कोड को कैसे छोटा बनाता है

//no more DataEnteredDelegate
class FirstViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showSecondViewController" {
            let secondViewController = segue.destinationViewController as! SecondViewController
            //secondViewController.delegate = self
            secondViewController.callback = { text in self.label.text = text }
        }
    }

    // required method of our custom DataEnteredDelegate protocol
    //func userDidEnterInformation(info: String) {
    //    label.text = info
    //}
}

और आखिरी में, शायद आप में से कोई व्यक्ति यह देख कर भ्रमित हो जाएगा कि हम केवल डेटा (इस मामले में बंद) को केवल एक तरीके से पास कर रहे हैं, पहले व्यू कंट्रोलर से दूसरे में, कोई सीधे दूसरे व्यू कंट्रोलर से वापस नहीं आ रहा है, हम कैसे कर सकते हैं इसे एक संचार उपकरण के रूप में मानते हैं? हो सकता है कि आप वास्तव में इसे चलाएं और इसे स्वयं साबित करें, सभी मैं कहूंगा कि यह पैरामीटर है , यह कॉलबैक क्लोजर का पैरामीटर है जो डेटा वापस पारित कर रहा है!

संपत्ति असाइन करके (डेटा को आगे भेजते हुए)

पुश करने या पेश करने से पहले आप अगले व्यू कंट्रोलर की संपत्ति बताकर सीधे डेटा पास कर सकते हैं।

class FirstViewController: UIViewController {

    func openSecondViewController() {

        // Here we initialize SecondViewController and set the id property to 492
        let secondViewController = SecondViewController()
        secondViewController.id = 492

        // Once it was assign we now push or present the view controller
        present(secondViewController, animated: true, completion: nil)
    }

}

class SecondViewController: UIViewController {
    
    var id: Int?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Here we unwrapped the id and will get the data from the previous view controller.
        if let id = id {
            print("Id was set: \(id)")
        }
    }
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow