दिलचस्प पोस्ट
अजगर में सूची और सूची के बीच अंतर क्या है? प्रश्न प्रश्न चिह्न एसक्यूएल प्रश्नों में क्या दर्शाता है? SQL सर्वर (localdb) \ v11.0 समझाया मैक ओएस एक्स तेंदुए कुंजी बाइंडिंग पर एमएक्स बराबर और GetHashCode के लिए सबसे अच्छी रणनीति क्या है? स्ट्रिंग लिटरल संशोधित रनटाइम / चेक / अनचेक / त्रुटि / अपवाद के बीच अंतर फ़ायरफ़ॉक्स या क्रोम में ActiveXObject (IE नहीं!) सी में अनुक्रम अंक एंड्रॉइड टुकड़ों में कस्टम विशेषताएँ JLabel में हाइपरलिंक कैसे जोड़ें MySQL से अंतिम N पंक्तियां चुनें फाइल कैसे एक जीआईटी रेपो से दूसरे (एक क्लोन नहीं) दूसरे स्थान पर, इतिहास को संरक्षित करने के लिए jquery .html () बनाम .append () चार से एक आइस्ट्रीम प्राप्त करें *

दृश्य नियंत्रकों के बीच डेटा पास करना

मैं आईओएस और, उद्देश्य- सी और पूरे एमवीसी प्रतिमान के लिए नया हूँ और मैं निम्नलिखित के साथ अटक गया हूं:

मेरे पास एक ऐसा दृश्य है जो डेटा प्रविष्टि फॉर्म के रूप में कार्य करता है और मैं उपयोगकर्ता को कई उत्पादों को चुनने का विकल्प देना चाहता हूं। उत्पादों को एक अन्य दृश्य पर सूचीबद्ध किया गया है जो कि UITableView नियंत्रक के साथ है और मैंने कई चयनों को सक्षम किया है।

मेरा प्रश्न यह है, मैं डेटा को एक दृश्य से दूसरे स्थान पर कैसे स्थानांतरित कर सकता हूं? मैं एक सरणी में UITableView पर चयनों को पकड़े रहूंगा, लेकिन फिर मैं इसे पिछले डाटा एंट्री फ़ॉर्म दृश्य में कैसे पारित करूं, ताकि इसे अन्य डेटा के साथ फार्म जमा करने के मूल डेटा के साथ सहेजा जा सके?

मैंने चारों ओर सर्फ किया है और देखा है कि कुछ लोग ऐप प्रतिनिधि में एक सरणी की घोषणा करते हैं। मैं सिंगलेटंस के बारे में कुछ पढ़ता हूं, लेकिन ये समझ में नहीं आ रहा कि ये क्या हैं और मैं एक डेटा मॉडल बनाने के बारे में कुछ पढ़ता हूं।

यह करने का सही तरीका क्या होगा और मैं इसके बारे में कैसे जाना होगा?

Solutions Collecting From Web of "दृश्य नियंत्रकों के बीच डेटा पास करना"

यह प्रश्न यहां स्टैक ओवरफ्लो पर बहुत लोकप्रिय हो रहा है, इसलिए मैंने सोचा कि मैं अपने जैसे आईओएस की दुनिया में शुरू होने वाले लोगों की मदद करने के लिए बेहतर उत्तर देने का प्रयास करूंगा।

मुझे उम्मीद है कि यह जवाब लोगों को समझने के लिए काफी स्पष्ट है और मुझे कुछ भी याद नहीं है।

पासिंग डेटा अग्रेषित

किसी अन्य दृश्य नियंत्रक से एक दृश्य नियंत्रक को आगे डेटा पास करना यदि आप एक ऑब्जेक्ट / वैल्यू को एक व्यू नियंत्रक से दूसरे दृश्य नियंत्रक तक पास करना चाहते हैं, तो आप इस विधि का उपयोग करेंगे, जो कि आप नेविगेशन स्टैक पर खड़े हो सकते हैं।

इस उदाहरण के लिए हमारे पास ViewControllerA और ViewControllerB

ViewControllerA से ViewControllerA लिए एक BOOL मान को पारित करने के लिए हम निम्न कार्य करेंगे।

  1. ViewControllerB.h में BOOL लिए एक संपत्ति बनाते हैं

     @property (nonatomic, assign) BOOL isSomethingEnabled; 
  2. ViewControllerA आपको इसे ViewControllerB बारे में बताने की ज़रूरत है, इसलिए एक का उपयोग करें

     #import "ViewControllerB.h" 

    फिर जहां आप दृश्य को लोड करना चाहते हैं didSelectRowAtIndex या कुछ IBAction आपको ViewControllerB में संपत्ति को सेट करने की आवश्यकता है इससे पहले कि आप नेव स्टैक पर इसे दबाएं।

     ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil]; viewControllerB.isSomethingEnabled = YES; [self pushViewController:viewControllerB animated:YES]; 

    यह सेट हो isSomethingEnabled में ViewControllerB में BOOL मान है YES

डेटा अग्रेषित सेगमेंट का उपयोग करते हुए

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

 -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 

तो ViewControllerA से ViewControllerA लिए एक BOOL पास करने के लिए हम निम्न कार्य करेंगे:

  1. ViewControllerB.h में BOOL लिए एक संपत्ति बनाते हैं

     @property (nonatomic, assign) BOOL isSomethingEnabled; 
  2. ViewControllerA आपको इसे ViewControllerB बारे में बताने की ज़रूरत है, इसलिए एक का उपयोग करें

     #import "ViewControllerB.h" 
  3. स्टोरीबोर्ड पर ViewControllerA से ViewControllerA से एक सेग्यू बनाएँ और इसे पहचानकर्ता दें, इस उदाहरण में हम इसे "showDetailSegue"

  4. इसके बाद हमें विधि को ViewControllerA जोड़ने की जरूरत होती है जिसे कहा जाता है कि जब कोई सीग्यू किया जाता है, इस वजह से हमें यह पता लगाने की आवश्यकता है कि किस सेग को बुलाया गया था और फिर कुछ करना था। हमारे उदाहरण में हम "showDetailSegue" जांच करेंगे और यदि वह प्रदर्शन किया गया है तो हम अपने BOOL मान को ViewControllerB

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

    यदि आपके विचारों को नेविगेशन नियंत्रक में एम्बेड किया गया है, तो आपको निम्न से ऊपर विधि को बदलने की आवश्यकता है

     -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([segue.identifier isEqualToString:@"showDetailSegue"]){ UINavigationController *navController = (UINavigationController *)segue.destinationViewController; ViewControllerB *controller = (ViewControllerB *)navController.topViewController; controller.isSomethingEnabled = YES; } } 

    यह सेट हो isSomethingEnabled में ViewControllerB में BOOL मान है YES

डेटा वापस पासिंग

ViewControllerB से ViewControllerB को वापस डेटा पास करने के लिए आपको प्रोटोकॉल और प्रतिनिधि या ब्लॉकों का उपयोग करना होगा , बाद के कॉलबैक के लिए ढीले युग्मित तंत्र के रूप में उपयोग किया जा सकता है।

ऐसा करने के लिए हम ViewControllerA को ViewControllerA एक प्रतिनिधि बना देगा। यह ViewControllerB को एक संदेश वापस देखने के लिए अनुमति देता है ViewControllerB हमें वापस डेटा भेजने के लिए सक्षम करता है।

ViewControllerA को ViewControllerA का प्रतिनिधि होने के लिए, ViewControllerB के प्रोटोकॉल के अनुरूप होना चाहिए, जिसे हमें निर्दिष्ट करना होगा। यह ViewControllerA बताता है कि कौन-से तरीकों को लागू करना चाहिए।

  1. ViewControllerB.h , #import नीचे, लेकिन @interface ऊपर आप प्रोटोकॉल निर्दिष्ट करते हैं।

     @class ViewControllerB; @protocol ViewControllerBDelegate <NSObject> - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item; @end 
  2. अगले अभी भी ViewControllerB.h आपको एक delegate संपत्ति सेटअप और ViewControllerB.m में संश्लेषित करने की आवश्यकता है

     @property (nonatomic, weak) id <ViewControllerBDelegate> delegate; 
  3. व्यू नियंत्रक में हम delegate को एक संदेश कहते हैं, जब हम दृश्य नियंत्रक को पॉप करते हैं।

     NSString *itemToPassBack = @"Pass this value back to ViewControllerA"; [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack]; 
  4. यह ViewControllerB लिए है अब ViewControllerA.h , ViewControllerA को ViewControllerB आयात ViewControllerB और इसके प्रोटोकॉल के अनुरूप बताएं।

     #import "ViewControllerB.h" @interface ViewControllerA : UIViewController <ViewControllerBDelegate> 
  5. ViewControllerA.m हमारे प्रोटोकॉल से निम्नलिखित विधि लागू करें

     - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item { NSLog(@"This was returned from ViewControllerB %@",item); } 
  6. नेविगेशन स्टैक को viewControllerB को viewControllerB जाने से पहले हमें ViewControllerB को बताने की आवश्यकता है कि ViewControllerA उसके प्रतिनिधि है, अन्यथा हमें एक त्रुटि मिल जाएगी

     ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil]; viewControllerB.delegate = self [[self navigationController] pushViewController:viewControllerB animated:YES]; 

संदर्भ

  • View Controller Programming Guide में अन्य दृश्य नियंत्रकों के साथ संवाद करने के लिए प्रतिनिधि का उपयोग करना
  • प्रतिनिधि पैटर्न

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

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

तीव्र

स्विफ्ट 3 के लिए अपडेट किया गया

यहां और स्टैक ओव्हरफ्लो के आस-पास और कई स्पष्टीकरण हैं, लेकिन अगर आप एक शुरुआती हैं, तो काम करने के लिए कुछ बुनियादी पाने की कोशिश कर रहे हैं, इस यूट्यूब ट्यूटोरियल को देखने का प्रयास करें (यह मुझे आखिर में यह कैसे समझने में मदद मिली है)।

  • यूट्यूब ट्यूटोरियल: सेग्यू (स्विफ्ट) के माध्यम से डेटा कैसे भेजा जाता है

अगली व्यू नियंत्रक के आगे डेटा पास करना

निम्नलिखित वीडियो के आधार पर एक उदाहरण है। यह विचार है कि द्वितीय दृश्य नियंत्रक में लेबल को प्रथम दृश्य नियंत्रक में टेक्स्ट फ़ील्ड से एक स्ट्रिंग पास करना है।

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

इंटरफ़ेस बिल्डर में स्टोरीबोर्ड लेआउट बनाएं सेगू बनाने के लिए, आप बस बटन पर क्लिक करें और दूसरा दृश्य नियंत्रक पर खींचें।

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

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

 import UIKit class FirstViewController: UIViewController { @IBOutlet weak var textField: UITextField! // This function is called before the segue override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // get a reference to the second view controller let secondViewController = segue.destination as! SecondViewController // set a variable in the second view controller with the String to pass secondViewController.receivedString = textField.text! } } 

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

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

 import UIKit class SecondViewController: UIViewController { @IBOutlet weak var label: UILabel! // This variable will hold the data being passed from the First View Controller var receivedString = "" override func viewDidLoad() { super.viewDidLoad() // Used the text from the First View Controller to set the label label.text = receivedString } } 

मत भूलो

  • UITextField और UILabel लिए दुकानों को हुक करें
  • आईबी में उचित स्विफ्ट फ़ाइलों के लिए पहला और दूसरा दृश्य नियंत्रक सेट करें।

पिछले दृश्य नियंत्रक को वापस डेटा पास करना

दूसरे दृश्य नियंत्रक से पहले दृश्य नियंत्रक को वापस डेटा पास करने के लिए, आप एक प्रोटोकॉल और एक प्रतिनिधि का उपयोग करते हैं। यह वीडियो उस प्रक्रिया के एक बहुत स्पष्ट चलना है:

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

निम्नलिखित वीडियो के आधार पर एक उदाहरण है (कुछ संशोधनों के साथ)

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

इंटरफ़ेस बिल्डर में स्टोरीबोर्ड लेआउट बनाएं दोबारा, सेगू बनाने के लिए, आप बस बटन से दूसरे दृश्य नियंत्रक तक खींचें। showSecondViewController लिए showSecondViewController पहचानकर्ता सेट करें। इसके अलावा, निम्नलिखित कोड में नामों का उपयोग करते हुए आउटलेट और कार्यों को हुक करने के लिए मत भूलना।

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

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

 import UIKit class FirstViewController: UIViewController, DataEnteredDelegate { @IBOutlet weak var label: UILabel! override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "showSecondViewController" { let secondViewController = segue.destination as! SecondViewController secondViewController.delegate = self } } func userDidEnterInformation(info: String) { label.text = info } } 

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

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

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

 import UIKit // 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? = nil @IBOutlet weak var textField: UITextField! @IBAction func sendTextBackButton(sender: AnyObject) { // call this method on whichever class implements our delegate protocol delegate?.userDidEnterInformation(info: textField.text!) // go back to the previous view controller _ = self.navigationController?.popViewController(animated: true) } } 

ध्यान दें कि protocol दृश्य नियंत्रक वर्ग से बाहर है।

बस। एप्लिकेशन को चलाना अब आप पहली बार दूसरे दृश्य नियंत्रक से डेटा को वापस भेजने में सक्षम होना चाहिए।

ऐसे कई तरीके हैं जिनके द्वारा आईओएस के किसी अलग वर्ग में डेटा प्राप्त किया जा सकता है। उदाहरण के लिए –

  1. दूसरे वर्ग के आवंटन के बाद प्रत्यक्ष आरंभ।
  2. प्रतिनिधि – वापस डेटा पास करने के लिए
  3. अधिसूचना – एक ही समय में कई वर्गों को डेटा प्रसारित करने के लिए
  4. NSUserDefaults में सहेजना – बाद में इसे एक्सेस करने के लिए
  5. सिंगलटन कक्षाएं
  6. डेटाबेस और अन्य भंडारण तंत्र जैसे plist, आदि

लेकिन मौजूदा वर्ग में आवंटन का एक अलग वर्ग के लिए मान पारित करने के सरल परिदृश्य के लिए, आवंटन के बाद सबसे आम और पसंदीदा तरीका मूल्यों की प्रत्यक्ष रूपरेखा होगी। यह अग्रानुसार होगा:-

हम इसे दो नियंत्रकों – कंट्रोलर 1 और कंट्रोलर 2 का उपयोग करके समझ सकते हैं

मान लें कि कंट्रोलर 1 वर्ग में आप कंट्रोलर 2 ऑब्जेक्ट बनाना चाहते हैं और उसे एक स्ट्रिंग मान दिया जा रहा है। यह इस रूप में किया जा सकता है: –

 - (void)pushToController2 { Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil]; [obj passValue:@"String"]; [self pushViewController:obj animated:YES]; } 

नियंत्रक 2 वर्ग के कार्यान्वयन में इस समारोह के रूप में होगा-

 @interface Controller2 : NSObject @property (nonatomic , strong) NSString* stringPassed; @end @implementation Controller2 @synthesize stringPassed = _stringPassed; - (void) passValue:(NSString *)value { _stringPassed = value; //or self.stringPassed = value } @end 

आप सीधे नियंत्रक 2 वर्ग के गुणों को भी इसी तरह से सेट कर सकते हैं:

 - (void)pushToController2 { Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil]; [obj setStringPassed:@"String"]; [self pushViewController:obj animated:YES]; } 

कई मानों को पारित करने के लिए आप कई मापदंडों का उपयोग कर सकते हैं जैसे: –

 Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil]; [obj passValue:@“String1” andValues:objArray withDate:date]; 

या यदि आपको 3 से अधिक पैरामीटर पारित करने की जरूरत है जो एक सामान्य सुविधा से संबंधित हैं तो आप मूल्य को मॉडल क्लास में स्टोर कर सकते हैं और उस मॉडल को अगले कक्षा में ऑब्जेक्ट पास कर सकते हैं

 ModelClass *modelObject = [[ModelClass alloc] init]; modelObject.property1 = _property1; modelObject.property2 = _property2; modelObject.property3 = _property3; Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil]; [obj passmodel: modelObject]; 

तो कम-से-कम अगर आप चाहते हैं –

 1) set the private variables of the second class initialise the values by calling a custom function and passing the values. 2) setProperties do it by directlyInitialising it using the setter method. 3) pass more that 3-4 values related to each other in some manner , then create a model class and set values to its object and pass the object using any of the above process. 

उम्मीद है की यह मदद करेगा

अधिक शोध के बाद यह प्रतीत होता है कि प्रोटोकॉल और डेलीगेट्स सही / एप्पल द्वारा ऐसा करने का पसंदीदा तरीका है।

मैं इस उदाहरण का उपयोग कर समाप्त हुआ

आईफोन देव एसडीके के दृश्य नियंत्रकों और अन्य ऑब्जेक्ट के बीच डेटा साझा करना

ठीक काम किया और मुझे एक स्ट्रिंग और एक सरणी को मेरे विचारों के बीच आगे और वापस करने की इजाजत दी।

आपकी सभी मदद का धन्यवाद

मुझे ब्लॉकों को पारित करने के साथ सबसे आसान और सबसे सुरुचिपूर्ण संस्करण मिल रहा है। आइए देखें दृश्य नियंत्रक जो लौटे हुए डेटा के लिए "ए" के रूप में प्रतीक्षा करता है और "नियंत्रक" को वापस देखने के लिए नियंत्रक "बी"। इस उदाहरण में हम 2 मान प्राप्त करना चाहते हैं: प्रथम प्रकार 1 और टाइप 2 की दूसरी संख्या।

मान लें कि हम स्टोरीबोर्ड का उपयोग करते हैं, पहले नियंत्रक कॉलबैक ब्लॉक सेट करते हैं, उदाहरण के लिए सेग्यू तैयारी के दौरान:

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.destinationViewController isKindOfClass:[BViewController class]]) { BViewController *viewController = segue.destinationViewController; viewController.callback = ^(Type1 *value1, Type2 *value2) { // optionally, close B //[self.navigationController popViewControllerAnimated:YES]; // let's do some action after with returned values action1(value1); action2(value2); }; } } 

और "बी" दृश्य नियंत्रक को कॉलबैक गुण घोषित करना चाहिए, BViewController.h:

 // it is important to use "copy" @property (copy) void(^callback)(Type1 *value1, Type2 *value2); 

कार्यान्वयन फ़ाइल में BViewController.m की तुलना में हमारे कॉलबैक वापस करने के लिए मानों को वांछित करने के बाद कहा जाना चाहिए:

 if (self.callback) self.callback(value1, value2); 

याद करने के लिए एक बात यह है कि ब्लॉक का उपयोग करने के लिए अक्सर मजबूत और __वेक संदर्भों का प्रबंधन करने की आवश्यकता होती है जैसे कि यहाँ समझाया गया है

दिए गए उत्तरों में से कुछ में कुछ अच्छी जानकारी है, लेकिन कोई भी सवाल पूरी तरह से नहीं पता।

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

मूल पोस्टर ने सिंग्लटोन के बारे में और ऐप डिलीएट के उपयोग के बारे में भी पूछा। इन सवालों के जवाब देने की आवश्यकता है।

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

आवेदन परिदृश्य

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

परिदृश्य एक: अधिकतम दो दृश्य नियंत्रकों को कभी भी जानकारी साझा करने की आवश्यकता है चित्र एक देखें

मूल समस्या का आरेख

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

परिदृश्य दो : दो से अधिक दृश्य नियंत्रकों को समान जानकारी साझा करने की आवश्यकता है। आरेख दो देखें

घर इन्वेंट्री अनुप्रयोग आरेख

आवेदन में चार दृश्य नियंत्रक हैं यह होम इन्वेंट्री प्रबंधन के लिए एक टैब-आधारित एप्लिकेशन है। तीन दृश्य नियंत्रक समान डेटा के अलग-अलग फ़िल्टर्ड दृश्य प्रस्तुत करते हैं:

  • ViewControllerA – लक्जरी आइटम
  • ViewControllerB – गैर बीमा आइटम
  • ViewControllerC – संपूर्ण होम इन्वेंटरी
  • ViewControllerD – नया आइटम फॉर्म जोड़ें

किसी भी समय किसी व्यक्तिगत आइटम का निर्माण या संपादित किया जाता है, उसे अन्य दृश्य नियंत्रकों के साथ भी सिंक्रनाइज़ करना चाहिए उदाहरण के लिए, अगर हम दृश्यकंट्रोलरडी में एक नाव जोड़ते हैं, लेकिन यह अभी तक बीमा नहीं है, तो उपयोगकर्ता को देखेंसींट्रोलरए (लक्जरी आइटम) और व्यू नियंत्रक सी (संपूर्ण होम इन्वेंटरी) में जाने पर बोट तब अवश्य दिखना चाहिए, लेकिन जब उपयोगकर्ता जाता है ViewControllerB (गैर-बीमाकृत आइटम) हमें न केवल नई चीजों को जोड़ने, बल्कि वस्तुओं को हटाना (जिसे चार दृश्य नियंत्रकों में से किसी से भी अनुमति दी जा सकती है), या मौजूदा आइटमों को संपादित करने के बारे में चिंतित होना चाहिए (जिसे "नया आइटम फॉर्म जोड़ें" से अनुमति दी जा सकती है संपादन के लिए)

चूंकि सभी दृश्य नियंत्रकों को समान डेटा साझा करने की ज़रूरत है, इसलिए सभी चार दृश्य नियंत्रकों को सिंक्रनाइज़ेशन में रहने की आवश्यकता है, और इसलिए अन्य सभी दृश्य नियंत्रकों के लिए संचार की किसी प्रकार की आवश्यकता होती है, जब भी कोई भी दृश्य नियंत्रक अंतर्निहित डेटा को बदलता है यह काफी स्पष्ट होना चाहिए कि हम प्रत्येक दृश्य नियंत्रक को इस परिदृश्य में एक दूसरे दृश्य नियंत्रक के साथ सीधे संवाद नहीं करना चाहते हैं। अगर यह स्पष्ट नहीं है, तो विचार करें कि हमारे पास 20 अलग-अलग दृश्य नियंत्रक हैं (केवल 4 के बजाय)। कितनी मुश्किल और त्रुटि प्रवण अन्य सभी 19 दृश्य नियंत्रकों को किसी भी समय एक दृश्य नियंत्रक एक परिवर्तन किया सूचित करने के लिए होगा?

समाधान: प्रतिनिधि और पर्यवेक्षक पैटर्न, और सिंगलटन

परिदृश्य में, हमारे पास कई व्यवहार्य समाधान हैं, जैसा कि अन्य उत्तर दिए गए हैं

  • segues
  • प्रतिनिधियों
  • दृश्य नियंत्रकों पर सीधे सेटिंग सेट करना
  • NSUserDefaults (वास्तव में एक खराब विकल्प)

परिदृश्य दो में, हमारे पास अन्य व्यवहार्य समाधान हैं:

  • प्रेक्षक पैटर्न
  • एकमात्र

एक सिंगलटन एक वर्ग का एक उदाहरण है, यह उदाहरण अपने जीवनकाल के दौरान अस्तित्व में एकमात्र उदाहरण है। एक सिंगलटन को इसका नाम इस तथ्य से मिलता है कि यह एकल उदाहरण है। सामान्य रूप से डेवलपर्स जो सिंगलटन का उपयोग करते हैं, उन्हें एक्सेस करने के लिए विशेष श्रेणी के तरीके हैं।

 + (HouseholdInventoryManager*) sharedManager; { static dispatch_once_t onceQueue; static HouseholdInventoryManager* _sharedInstance; // dispatch_once is guaranteed to only be executed once in the // lifetime of the application dispatch_once(&onceQueue, ^{ _sharedInstance = [[self alloc] init]; }); return _sharedInstance; } 

अब जब हम समझते हैं कि एक सिंगलटन क्या है, तो चर्चा करें कि सिंगलटन ऑब्ज़र्वर पैटर्न में कैसे फिट बैठता है। पर्यवेक्षक पैटर्न का उपयोग किसी एक ऑब्जेक्ट के परिवर्तनों का जवाब देने के लिए किया जाता है। दूसरे परिदृश्य में, हमारे पास चार अलग-अलग दृश्य नियंत्रक हैं, जो सभी को अंतर्निहित डेटा में परिवर्तनों के बारे में जानना चाहते हैं। "अंतर्निहित डेटा" एक एकल उदाहरण, एक सिंगलटन से संबंधित होना चाहिए। सिंगलटन में किए गए परिवर्तनों को देखकर "परिवर्तनों के बारे में पता" पूरा किया गया है

घर इन्वेंट्री एप्लिकेशन में एक ऐसा क्लास का एक उदाहरण होगा जो इन्वेंट्री आइटमों की सूची प्रबंधित करने के लिए डिज़ाइन किया गया है। प्रबंधक घरेलू सामानों के संग्रह का प्रबंधन करेगा डेटा प्रबंधक के लिए निम्नलिखित क्लास की परिभाषा है:

 #import <Foundation/Foundation.h> @class JGCHouseholdInventoryItem; @interface HouseholdInventoryManager : NSObject /*! The global singleton for accessing application data */ + (HouseholdInventoryManager*) sharedManager; - (NSArray *) entireHouseholdInventory; - (NSArray *) luxuryItems; - (NSArray *) nonInsuredItems; - (void) addHouseholdItemToHomeInventory:(JGCHouseholdInventoryItem*)item; - (void) editHouseholdItemInHomeInventory:(JGCHouseholdInventoryItem*)item; - (void) deleteHoueholdItemFromHomeInventory:(JGCHouseholdInventoryItem*)item; @end 

जब घर इन्वेंट्री आइटम का संग्रह बदलता है, तो दृश्य नियंत्रकों को इस बदलाव के बारे में पता होना चाहिए। ऊपर की कक्षा परिभाषा यह स्पष्ट नहीं करती कि यह कैसे होगा। हमें पर्यवेक्षक पैटर्न का पालन करना होगा दृश्य नियंत्रकों को औपचारिक रूप से साझा मैनेजर का पालन करना चाहिए। किसी अन्य वस्तु को ध्यान में रखने के दो तरीके हैं:

  • कुंजी-मान-अवलोकन (केवीओ)
  • NSNotificationCenter।

परिदृश्य दो में, हमारे पास घरेलू इन्वेंटरी मैनेजर की कोई संपत्ति नहीं है जो केवीओ का उपयोग करके देखा जा सकता है। क्योंकि हमारे पास एक ऐसी संपत्ति नहीं है जो आसानी से देखे जा सकते हैं, इस मामले में पर्यवेक्षक पैटर्न NSNotificationCenter का उपयोग करके कार्यान्वित किया जाना चाहिए। चार दृश्य नियंत्रकों में से प्रत्येक नोटिफिकेशन की सदस्यता लेता है, और जब उचित हो तो साझा प्रबंधक को अधिसूचना केंद्र को नोटिफिकेशन भेजना होगा। इन्वेंट्री मैनेजर को देखने नियंत्रकों के बारे में कुछ और किसी भी अन्य वर्ग के उदाहरणों को जानने की ज़रूरत नहीं है, जो इन्वेंट्री आइटमों के संग्रह को बदलते समय जानने में रुचि रख सकते हैं; NSNotificationCenter इन कार्यान्वयन के विवरण का ख्याल रखता है व्यू नियंत्रक बस सूचनाओं की सदस्यता लेते हैं, और डेटा प्रबंधक केवल सूचनाएं पोस्ट करता है

कई शुरुआती प्रोग्रामर इस तथ्य का लाभ उठाते हैं कि आवेदन के जीवनकाल में हमेशा एक आवेदन प्रतिनिधि होता है, जो विश्व स्तर पर सुलभ है। शुरुआत में प्रोग्रामर इस वस्तु का उपयोग वस्तुओं की वस्तुओं और कार्यक्षमता को एप्लिकेशन डिलीएगेट में उपयोग करते हैं, क्योंकि आवेदन में कहीं और तक पहुंचने की सुविधा है। सिर्फ इसलिए कि AppDelegate एक सिंगलटन का मतलब यह नहीं है कि उसे अन्य सभी गीतों को बदलना चाहिए। यह एक खराब अभ्यास है क्योंकि यह एक वर्ग पर बहुत अधिक बोझ डालता है, अच्छा ऑब्जेक्ट ओरिएंटेड प्रथाओं को तोड़ता है। प्रत्येक वर्ग की एक स्पष्ट भूमिका होनी चाहिए जिसे आसानी से समझाया जाता है, अक्सर क्लास के नाम से।

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

संदर्भ

  • व्यू नियंत्रकों के बीच डेटा फ्लो को प्रबंधित करना
  • दृश्य नियंत्रकों के बीच डेटा पासिंग
  • उद्देश्य-सी में अतुल्यकालिक JSON अनुरोध

डेटा साझा करने के लिए कई तरीके हैं

  1. आप NSUserDefaults का उपयोग करके हमेशा डेटा साझा कर सकते हैं वह मान सेट करें जिसे आप अपनी पसंद की कुंजी के संबंध में साझा करना चाहते हैं और अगले दृश्य नियंत्रक में उस कुंजी से जुड़े NSUserDefault से मान प्राप्त करें

     [[NSUserDefaults standardUserDefaults] setValue:value forKey:key] [[NSUserDefaults standardUserDefaults] objectForKey:key] 
  2. आप केवल viewcontrollerA में एक संपत्ति बना सकते हैं। viewcontrollerA में viewcontrollerB का एक ऑब्जेक्ट बनाएं और उस संपत्ति के लिए वांछित मूल्य असाइन करें।

  3. आप इसके लिए कस्टम प्रतिनिधि भी बना सकते हैं।

ViewController 2 (गंतव्य) से डेटा को वापस देखने के लिए नियंत्रक 1 (स्रोत) अधिक दिलचस्प बात है यह मानते हुए कि आप कहानी का उपयोग करते हैं, उन सभी तरीकों से मुझे पता चला है:

  • प्रतिनिधि
  • अधिसूचना
  • उपयोगकर्ता डिफ़ॉल्ट
  • एकाकी वस्तु

उन पर पहले से ही चर्चा हुई थी

मैंने पाया कि वहां अधिक तरीके हैं:

ब्लॉक कॉलबैक का उपयोग करना:

इसे prepareForSegue 1 में prepareForSegue विधि में उपयोग करें

 NextViewController *destinationVC = (NextViewController *) segue.destinationViewController; [destinationVC setDidFinishUsingBlockCallback:^(NextViewController *destinationVC) { self.blockLabel.text = destination.blockTextField.text; }]; 

स्टोरीबोर्ड का उपयोग करना खोलें (बाहर निकलें)

VC 1 में एक UIStoryboardSegue तर्क के साथ एक विधि को लागू करें, इस तरह से:

 -(IBAction)UnWindDone:(UIStoryboardSegue *)segue { } 

In the storyBoard hook the "return" button to the green Exit button(Unwind) of the vc. Now you have a segue that "goes back" so u can use the destinationViewController property in the prepareForSegue of VC2 and change any property of VC1 before it goes back.

  • Another option of using storyboards Undwind (Exit) – you can use the method you wrote in VC1

     -(IBAction)UnWindDone:(UIStoryboardSegue *)segue { NextViewController *nextViewController = segue.sourceViewController; self.unwindLabel.text = nextViewController.unwindPropertyPass; } 

    And in the prepareForSegue of VC1 you can change any property you want to share.

In both unwind options you can set the tag property of the button and check it in the prepareForSegue.

Hope i added something to the discussion.

🙂 Cheers.

The OP didn't mention view controllers but so many of the answers do, that I wanted to chime in with what some of the new features of the LLVM allow to make this easier when wanting to pass data from one view controller to another and then getting some results back.

Storyboard segues, ARC and LLVM blocks make this easier than ever for me. Some answers above mentioned storyboards and segues already but still relied on delegation. Defining delegates certainly works but some people may find it easier to pass pointers or code blocks.

With UINavigators and segues, there are easy ways of passing information to the subservient controller and getting the information back. ARC makes passing pointers to things derived from NSObjects simple so if you want the subservient controller to add/change/modify some data for you, pass it a pointer to a mutable instance. Blocks make passing actions easy so if you want the subservient controller to invoke an action on your higher level controller, pass it a block. You define the block to accept any number of arguments that makes sense to you. You can also design the API to use multiple blocks if that suits things better.

Here are two trivial examples of the segue glue. The first is straightforward showing one parameter passed for input, the second for output.

 // Prepare the destination view controller by passing it the input we want it to work on // and the results we will look at when the user has navigated back to this controller's view. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { [[segue destinationViewController] // This parameter gives the next controller the data it works on. segueHandoffWithInput:self.dataForNextController // This parameter allows the next controller to pass back results // by virtue of both controllers having a pointer to the same object. andResults:self.resultsFromNextController]; } 

This second example shows passing a callback block for the second argument. I like using blocks because it keeps the relevant details close together in the source – the higher level source.

 // Prepare the destination view controller by passing it the input we want it to work on // and the callback when it has done its work. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { [[segue destinationViewController] // This parameter gives the next controller the data it works on. segueHandoffWithInput:self.dataForNextController // This parameter allows the next controller to pass back results. resultsBlock:^(id results) { // This callback could be as involved as you like. // It can use Grand Central Dispatch to have work done on another thread for example. [self setResultsFromNextController:results]; }]; } 

If you want to pass data from one controller to other try this code

FirstViewController.h

 @property (nonatomic, retain) NSString *str; 

SecondViewController.h

 @property (nonatomic, retain) NSString *str1; 

FirstViewController.m

 - (void)viewDidLoad { // message for the second SecondViewController self.str = @"text message"; [super viewDidLoad]; } -(IBAction)ButtonClicked { SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; secondViewController.str1 = str; [self.navigationController pushViewController:secondViewController animated:YES]; } 

I was searching this solution for long time, Atlast I found it. First of all declare all the objects in your SecondViewController.h file like

 @interface SecondViewController: UIviewController { NSMutableArray *myAray; CustomObject *object; } 

Now in your implementation file allocate the memory for those objects like this

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization myAray=[[NSMutableArray alloc] init]; object=[[CustomObject alloc] init]; } return self; } 

Now you have allocated the memory for Array and object. now you can fill that memory before pushing this ViewController

Go to your SecondViewController.h and write two methods

 -(void)setMyArray:(NSArray *)_myArray; -(void)setMyObject:(CustomObject *)_myObject; 

in implementation file you can implement the function

 -(void)setMyArray:(NSArray *)_myArray { [myArra addObjectsFromArray:_myArray]; } -(void)setMyObject:(CustomObject *)_myObject { [object setCustomObject:_myObject]; } 

expecting that your CustomObject must have a setter function with it.

now your basic work is done. go to the place where you want to push the SecondViewController and do the following stuff

 SecondViewController *secondView= [[SecondViewController alloc] initWithNibName:@"SecondViewController " bundle:[NSBundle MainBundle]] ; [secondView setMyArray:ArrayToPass]; [secondView setMyObject:objectToPass]; [self.navigationController pushViewController:secondView animated:YES ]; 

Take care for spelling mistakes.

This is not the way to do it, you should use delegates, I'll assume we have two view controllers ViewController1 and ViewController2 and this check thing is in the first one and when its state changes, you want to do something in ViewController2, to achieve that in the proper way, you should do the below:

Add a new file to your project (Objective-C Protocol) File -> New, now name it ViewController1Delegate or whatever you want and write these between the @interface and @end directives

 @optional - (void)checkStateDidChange:(BOOL)checked; 

Now go to ViewController2.h and add

 #import "ViewController1Delegate.h" 

then change its definition to

 @interface ViewController2: UIViewController<ViewController1Delegate> 

Now go to ViewController2.m and inside the implementation add:

 - (void)checkStateDidChange:(BOOL)checked { if (checked) { // Do whatever you want here NSLog(@"Checked"); } else { // Also do whatever you want here NSLog(@"Not checked"); } } 

Now go to ViewController1.h and add the following property:

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

Now if you are creating ViewController1 inside ViewController2 after some event, then you should do it this way using NIB files:

 ViewController1* controller = [[NSBundle mainBundle] loadNibNamed:@"ViewController1" owner:self options:nil][0]; controller.delegate = self; [self presentViewController:controller animated:YES completion:nil]; 

Now you are all set, whenever you detect the event of check changed in ViewController1, all you have to do is the below

 [delegate checkStateDidChange:checked]; // You pass here YES or NO based on the check state of your control 

Please tell me if there's anything that's not clear of if I didn't understand your question properly.

If you want to send data from one to another viewController, here's a way to it:

Say we have viewControllers: viewControllerA and viewControllerB

Now in viewControllerB.h

 @interface viewControllerB : UIViewController { NSString *string; NSArray *array; } - (id)initWithArray:(NSArray)a andString:(NSString)s; 

In viewControllerB.m

 #import "viewControllerB.h" @implementation viewControllerB - (id)initWithArray:(NSArray)a andString:(NSString)s { array = [[NSArray alloc] init]; array = a; string = [[NSString alloc] init]; string = s; } 

In viewControllerA.m

 #import "viewControllerA.h" #import "viewControllerB.h" @implementation viewControllerA - (void)someMethod { someArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil]; someString = [NSString stringWithFormat:@"Hahahahaha"]; viewControllerB *vc = [[viewControllerB alloc] initWithArray:someArray andString:someString]; [self.navigationController pushViewController:vc animated:YES]; [vc release]; } 

So this is how you can pass data from viewControllerA to viewControllerB without setting any delegate. 😉

1. Create the instance of first View Controller in the second View Controller and make its property @property (nonatomic,assign) .

2. Assign the SecondviewController instance of this view controller.

2. When you finish the selection operation copy the array to first View Controller,When u unload the SecondView ,FirstView will hold the Array Data.

Hope This Helps.

Passing Data between FirstViewController to SecondViewController as below

उदाहरण के लिए:

FirstViewController String value as

 StrFirstValue = @"first"; 

so we can pass this value in second class using below step

1>We need to crate string object in SecondViewController.h file

 NSString *strValue; 

2>Need to declare property as below below declaration in .h file

 @property (strong, nonatomic) NSString *strSecondValue; 

3>Need synthesize that value in FirstViewController.m file below header declaration

 @synthesize strValue; 

and in FirstViewController.h :

 @property (strong, nonatomic) NSString *strValue; 

4>In FirstViewController,From which method we navigate to second view please write below code in that method.

 SecondViewController *secondView= [[SecondViewController alloc] initWithNibName:@"SecondViewController " bundle:[NSBundle MainBundle]]; [secondView setStrSecondValue:StrFirstValue]; [self.navigationController pushViewController:secondView animated:YES ]; 

I am currently contributing to an open source solution to this problem through a project called MCViewFactory, which may be found here:

https://github.com/YetiHQ/manticore-iosviewfactory

The idea is imitate Android's intent paradigm, using a global factory to manage which view you are looking at and using "intents" to switch and pass data between views. All the documentation is on the github page, but here are some highlights:

You setup all your views in .XIB files and register them in the app delegate, while initializing the factory.

 // Register activities MCViewFactory *factory = [MCViewFactory sharedFactory]; // the following two lines are optional. [factory registerView:@"YourSectionViewController"]; 

Now, in your VC, anytime you want to move to a new VC and pass data, you create a new intent and add data to its dictionary (savedInstanceState). Then, just set the current intent of factory:

 MCIntent* intent = [MCIntent intentWithSectionName:@"YourSectionViewController"]; [intent setAnimationStyle:UIViewAnimationOptionTransitionFlipFromLeft]; [[intent savedInstanceState] setObject:@"someValue" forKey:@"yourKey"]; [[intent savedInstanceState] setObject:@"anotherValue" forKey:@"anotherKey"]; // ... [[MCViewModel sharedModel] setCurrentSection:intent]; 

All of your views that conform to this need to be subclasses of MCViewController, which allow you to override the new onResume: method, allowing you access to the data you've passed in.

 -(void)onResume:(MCIntent *)intent { NSObject* someValue = [intent.savedInstanceState objectForKey:@"yourKey"]; NSObject* anotherValue = [intent.savedInstanceState objectForKey:@"anotherKey"]; // ... // ensure the following line is called, especially for MCSectionViewController [super onResume:intent]; } 

Hope some of you find this solution useful/interesting.

In my case I used a singleton class which can work as a global object allowing accesses to the data from almost everywhere in the app. First thing is to build a singleton class. Please refer to the page," What should my Objective-C singleton look like? " And what I did to make the object globally accessible was simply import it in appName_Prefix.pch which is for applying import statement in every classes. To access this object and to use, I simply implemented class method to return the shared instance, which contains its own variables

Create the property on next view controller .h and define getter and setter.

Add this property in NextVC.h on nextVC

 @property (strong, nonatomic) NSString *indexNumber; 

Add

@synthesize indexNumber; in NextVC.m

And last

 NextVC *vc=[[NextVC alloc]init]; vc.indexNumber=@"123"; [self.navigationController vc animated:YES]; 

I know this is a beaten subject but for those looking to answer this question with a SWIFT slant and want a bare-bones example, here my go-to method for passing data if you are using a segue to get around.

It is similar to the above but without the buttons, labels and such. Just simply passing data from one view to the next.

Setup The Storyboard

There are three parts.

  1. The Sender
  2. The Segue
  3. The Receiver

This is a very simple view layout with a segue between them.


Very simple view layout.  Note : No navigation controller


Here is the setup for the sender


The Sender


Here is the setup for the receiver.


The Receiver


Lastly, the setup for the segue.


The Segue Identifier


The View Controllers

We are keeping this simple so no buttons, not actions, we are simply moving data from the sender to the receiver when the application loads and then outputting the transmitted value to the console.

This page takes the initially loaded value and passes it along.

 // // ViewControllerSender.swift // PassDataBetweenViews // // Created by Chris Cantley on 8/25/15. // Copyright (c) 2015 Chris Cantley. All rights reserved. // import UIKit class ViewControllerSender: UIViewController { // THE STUFF - put some info into a variable let favoriteMovie = "Ghost Busters" override func viewDidAppear(animated: Bool) { // PASS IDENTIFIER - go to the recieving view controller. self.performSegueWithIdentifier("goToReciever", sender: self) } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { //GET REFERENCE - ...to the receiver view. var viewControllerReceiver = segue.destinationViewController as? ViewControllerReceiver //PASS STUFF - pass the variable along to the target. viewControllerReceiver!.yourFavMovie = self.favoriteMovie } } 

This page just sends the value of the variable to the console when it loads. By this point our favorite movie should be in that variable.

 // // ViewControllerReceiver.swift // PassDataBetweenViews // // Created by Chris Cantley on 8/25/15. // Copyright (c) 2015 Chris Cantley. All rights reserved. // import UIKit class ViewControllerReceiver: UIViewController { //Basic empty variable waiting for you to pass in your fantastic favorite movie. var yourFavMovie = "" override func viewDidLoad() { super.viewDidLoad() //And now we can view it in the console. println("The Movie is \(self.yourFavMovie)") } } 

That is how you can tackle it if you want to use a segue and you don't have your pages under a navigation controller.

Once it is run it should switch to the receiver view automatically and pass the value from the sender to the receiver, displaying the value in the console.

Ghost Busters is a classic folks.

NewsViewController

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tbl_View deselectRowAtIndexPath:indexPath animated:YES]; News *newsObj = [newstitleArr objectAtIndex:indexPath.row]; NewsDetailViewController *newsDetailView = [[NewsDetailViewController alloc] initWithNibName:@"NewsDetailViewController" bundle:nil]; newsDetailView.newsHeadlineStr = newsObj.newsHeadline; [self.navigationController pushViewController:newsDetailView animated:YES]; } 

NewsDetailViewController.h

 @interface NewsDetailViewController : UIViewController @property(nonatomic,retain) NSString *newsHeadlineStr; @end 

NewsDetailViewController.m

 @synthesize newsHeadlineStr; 

Delegation is the only one solution to perform such operations when you are using .xib files however all answers described above are for storyboard for .xibs files you need to use delegation. that's only solution you can.

Another solution is use singleton class pattern initialize it once and use it in your entire app.

if you wants to pass data from ViewControlerOne to ViewControllerTwo try these..

do these in ViewControlerOne.h

  @property (nonatomic, strong) NSString *str1; 

do these in ViewControllerTwo.h

  @property (nonatomic, strong) NSString *str2; 

Synthesize str2 in ViewControllerTwo.m

 @interface ViewControllerTwo () @end @implementation ViewControllerTwo @synthesize str2; 

do these in ViewControlerOne.m

  - (void)viewDidLoad { [super viewDidLoad]; // Data or string you wants to pass in ViewControllerTwo.. self.str1 = @"hello world"; } 

on the buttons click event do this..

 -(IBAction)ButtonClicked { //Navigation on buttons click event from ViewControlerOne to ViewControlerTwo with transferring data or string.. ViewControllerTwo *objViewTwo=[self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerTwo"]; obj.str2=str1; [self.navigationController pushViewController: objViewTwo animated:YES]; } 

do these in ViewControllerTwo.m

 - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"%@",str2); } 

You can save data in App delegate to access it across view controllers in your application. All you have to do is create a shared instance of app delegate

 AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 

For Example

if you declare a NSArray object *arrayXYZ then you can access it in any view controller by appDelegate.arrayXYZ

There are tons of ways to do this and its important to pick the right one. Probably one of the biggest architectural decisions lies on how model code will be shared or accessed throughout the app.

I wrote a blog post about this a while back: Sharing Model Code . Here's a brief summary:

Shared data

One approach is to share pointers to the model objects between view controllers.

  • Brute force iteration on view controllers (in Navigation or Tab Bar Controller) to set the data
  • Set data in prepareForSegue (if storyboards) or init (if programmatic)

Since prepare for segue is the most common here is an example:

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { var next = segue.destinationViewController as NextViewController next.dataSource = dataSource } 

Independent access

Another approach is to handle a screen full of data at a time and instead of coupling the view controllers to each other couple each view controller to single data source that they can get to independently.

The most common way I've seen this done is through a singleton instance. So if your singleton object was dataAccess you could do the following in the viewDidLoad method of UIViewController:

 func viewDidLoad() { super.viewDidLoad() var data = dataAccess.requestData() } 

There are addition tools that also help pass along data:

  • Key-Value Observing
  • NSNotification
  • Core Data
  • NSFetchedResultsController
  • Data Source

Core Data

The nice thing about Core Data is that it has inverse relationships. So if you want to just give a NotesViewController the notes object you can because it'll have an inverse relationship to something else like notebook. If you need data on the notebook in the NotesViewController you can walk back up the object graph by doing the following:

 let notebookName = note.notebook.name 

Read more about this on my blog post: Sharing Model Code

If you want to send data from one to another viewController, here's a way to it:

Say we have viewControllers: ViewController and NewViewController.

in ViewController.h

 #import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UITextField *mytext1,*mytext2,*mytext3,*mytext4; } @property (nonatomic,retain) IBOutlet UITextField *mytext1,*mytext2,*mytext3,*mytext4; -(IBAction)goToNextScreen:(id)sender; @end 

in ViewController.m

 #import "ViewController.h" #import "NewViewController.h" @implementation ViewController @synthesize mytext1,mytext2,mytext3,mytext4; -(IBAction)goToNextScreen:(id)sender { NSArray *arr = [NSArray arrayWithObjects:mytext1.text,mytext2.text,mytext3.text,mytext4.text, nil]; NewViewController *newVc = [[NewViewController alloc] initWithNibName:@"NewViewController" bundle:nil]; newVc.arrayList = arr; [self.navigationController pushViewController:newVc animated:YES]; } 

In NewViewController.h

 #import <UIKit/UIKit.h> @interface NewViewController : UITableViewController { NSArray *arrayList; NSString *name,*age,*dob,*mobile; } @property(nonatomic, retain)NSArray *arrayList; @end 

In NewViewController.m

 #import "NewViewController.h" #import "ViewController.h" @implementation NewViewController @synthesize arrayList; #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return [arrayList count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } // Configure the cell... cell.textLabel.text = [arrayList objectAtIndex:indexPath.row]; return cell; } @end 

So this way we can pass the data from one viewcontroller to another view controller…

I like the idea of Model objects and Mock objects based on NSProxy to commit or discard data if what user selects can be cancelled.

It's easy to pass data around since it's single object or couple of objects and if you have let's say UINavigationController controller, you can keep the reference to model inside and all pushed view controllers can access it directly from navigation controller.

I have seen a lot of people over complicating this using the didSelectRowAtPath method. I am using Core Data in my example.

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ //this solution is for using Core Data YourCDEntityName * value = (YourCDEntityName *)[[self fetchedResultsController] objectAtIndexPath: indexPath]; YourSecondViewController * details = [self.storyboard instantiateViewControllerWithIdentifier:@"nameOfYourSecondVC"];//make sure in storyboards you give your second VC an identifier //Make sure you declare your value in the second view controller details.selectedValue = value; //Now that you have said to pass value all you need to do is change views [self.navigationController pushViewController: details animated:YES]; } 

4 lines of code inside the method and you are done.

There are many answers to this questions offering many different ways to perform view controller communication that would indeed work, but I don't see anywhere mentioned which one are actually best to use and which ones to avoid.

In practice, in my opinion only a few solutions are recommended:

  • To pass data forward:
    • override the prepare(for:sender:) method of UIViewController when using a storyboard and segues
    • pass data through an initializer or through properties when performing view controller transitions thtough code
  • To pass data backwards
    • update the app shared state (which you can pass forward between view controllers with either one of the methods above)
    • use delegation
    • use an unwind segue

Solutions I recommend NOT to use:

  • Referencing the previous controller directly instead of using delegation
  • Sharing data through a singleton
  • Passing data through the app delegate
  • Sharing data through the user defaults
  • Passing data through notifications

These solutions, although working in the short term, introduce too many dependencies that will garble the architecture of the app and create more problems later.

For those interested, I wrote some articles that address these points more in depth and highlight the various drawbacks:

  • How iOS View Controllers Communicate With Each Other
  • How to Structure the Code of iOS Apps
  • Understanding the Core Architectural Principles of iOS Development with a Practical Example

This is a really great tutorial for anyone that wants one. Here is the example code:

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"myIdentifer]) { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; myViewController *destViewController = segue.destinationViewController; destViewController.name = [object objectAtIndex:indexPath.row]; } }