2008-10-28 18 views
7

मैं इस हफ्ते पहले अपने सिर को खरोंच कर रहा था, और अब मेरे बेल्ट के नीचे थोड़ी अधिक कोको अनुभव के साथ मुझे लगता है कि मुझे क्या हो रहा है के बारे में एक स्याही है।क्या parentViewController हमेशा एक नेविगेशन नियंत्रक है?

मैं एक ऐसा ऐप्लिकेशन बना रहा हूं जो UINavigationController द्वारा संचालित है। ऐपडिलेगेट में, मैं रूट व्यू कंट्रोलर के रूप में "पेज 1" का उपयोग करके इस कक्षा का एक उदाहरण बना देता हूं।

UINavigationController *aNavigationController = [[UINavigationController alloc] 
    initWithRootViewController:page1ViewController]; 

अब यहां समस्या है जहां मुझे समस्या है। "पृष्ठ 1" से मैं एक मॉडल दृश्य नियंत्रक का उपयोग करना चाहता हूं जो इंटरफ़ेस पर स्लाइड करता है और फिर उपयोगकर्ता द्वारा संपादित किए जाने के बाद गायब हो जाता है। मैं इस तरह कोड का उपयोग कर कि, Page1ViewController के अंदर कार्य करें:

[self presentModalViewController:myModalViewController animated:YES]; 

जब मॉडल देखें नियंत्रक चला गया है, मैं एक मूल्य "पृष्ठ 1" पर क्या उपयोगकर्ता मॉडल देखें नियंत्रक में दर्ज किए गए के आधार पर बदलना चाहते हैं। तो, मैं इस तरह की कुछ कोड है, जो मॉडल देखें नियंत्रक में रहता है ने लिखा है:

[self.parentViewController dismissModalViewControllerAnimated:YES]; 
[self.parentViewController doSomethingPleaseWithSomeData:someData]; 

पेज 1 करने के लिए अद्यतन नहीं हो रहा था, और यह मुझे काफी समय लगा एहसास है कि "doSomethingPleaseWithSomeData" संदेश था Page1ViewController पर नहीं भेजा जा रहा है, लेकिन नेविगेशन नियंत्रक।

क्या नेविगेशन नियंत्रकों का उपयोग करते समय यह हमेशा उम्मीद की जा सकती है? क्या मैंने शायद कुछ गलत तरीके से कॉन्फ़िगर किया था? क्या मैं चाहता हूं कि व्यू कंट्रोलर पर जाने का कोई आसान तरीका है (इस मामले में, पेज 1 व्यू कंट्रोलर)।

उत्तर

14

मैं आपकी समस्या का समाधान करने के लिए प्रतिनिधिमंडल पैटर्न का उपयोग करने की सलाह दूंगा। एक संपत्ति

@property (nonatomic, assign) id <MyModalViewDelegate> delegate; 

और एक इसी प्रोटोकॉल

@protocol MyModalViewDelegate 
@optional 
    - (void)myModalViewControllerDidFinish:(MyModalViewController *)aModalViewController; 
@end 

इस संदेश बनाएँ उपयोगकर्ता अपने दृश्य के साथ खत्म जब (उदाहरण के लिए टैप करता सहेजें बटन), भेजें:

if ([self.delegate respondsToSelector:@selector(myModalViewControllerDidFinish:)]) 
    [self.delegate myModalViewControllerDidFinish:self]; 

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

इस प्रकार ऐप्पल इस समस्या को हल करता है, उदाहरण के लिए, UIImagePickerController और UIPersonPickerController।

4

आप इसे संभालने के कुछ तरीके हैं।

myModalViewController.logicalParent = self; //page1Controller 
[self presentModalViewController:myModalViewController animated:YES]; 

बस सुनिश्चित करें कि आप myModalViewController करने के लिए उपयुक्त उदाहरण चर @property जोड़ने के लिए, और logicalParent के लिए @synthesize करें, फिर: सरल शायद सिर्फ myModalViewController में एक UIViewController संपत्ति जोड़ सकते हैं और page1Controller के लिए सेट करने के लिए इससे पहले कि आप को पेश है आपके पास व्यू कंट्रोलर पर डेटा को संवाद करने का एक तरीका होगा जो मोडल संवाद को ट्रिगर करता है। यह आपको धक्का देने और उन्हें ढेर पर पॉप करने से पहले नेविगेशन के विभिन्न स्तरों के बीच डेटा आगे और आगे जाने के लिए भी है।

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

+0

ठीक वही है जो मैं चाहता हूं, धन्यवाद! मैं कोको में नया हूं, लेकिन एमवीसी के लिए नहीं। हालांकि, जावा वेब डेवलपर होने के बावजूद मैं हमेशा भूल जाता हूं कि "सी" में नियंत्रक एक दूसरे के साथ बातचीत कर सकते हैं! – bpapa

+0

एक अच्छा जवाब है, लेकिन यह मामला क्यों है? यह स्पष्ट रूप से * नहीं * उस मामले में है कि मोडल व्यू का parentViewController किसी भी तार्किक अर्थ में नेविगेशन नियंत्रक है (पृष्ठ 1 नियंत्रक मोडल डिस्प्ले के लिए पूछने वाला नियंत्रक है), तो कोको टच इसे इस तरह क्यों सेट करता है? –

1

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

मुझे लगता है कि यह एक बग है: या तो, या दस्तावेज अपूर्ण लगता है। मैं पूछताछ करूंगा।

1

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

- (void)presentModalViewController:(UIViewController *)c { 
    [self.navigationHierarchy removeAllObjects]; 
    [self.navigationHierarchy addObjectsFromArray:[navigation viewControllers]]; 
    [navigation setViewControllers:[NSArray array] animated:YES]; 
    [navigation presentModalViewController:c animated:YES]; 
} 

- (void)dismissModalViewController { 
    [navigation dismissModalViewControllerAnimated:YES]; 
    [navigation setViewControllers:[NSArray arrayWithArray:self.navigationHierarchy] animated:YES]; 
} 

इन दो तरीकों परिभाषित कर रहे हैं, जहां मैं मुख्य नेविगेशन hiererchy बनाए रखने: ऐप प्रतिनिधि। नेविगेशन और नेविगेशन श्रेणीबद्धता इस प्रकार परिभाषित की गई हैं:

NSMutableArray *navigationHierarchy; 
UINavigationController *navigation; 
संबंधित मुद्दे