2011-10-20 9 views
29

के बीच अलग-अलग addSubview व्यवहार, आईओएस 4.3 में कोडिंग करते समय, मुझे [superview addSubView:controller.view] के साथ किसी अन्य दृश्य में व्यू कंट्रोलर का दृश्य जोड़ने के दौरान पाया गया, नियंत्रक उदाहरण -viewWillAppear/viewDidAppear संदेश प्राप्त नहीं करेगा, मुझे एक ही समस्या मिली ढेर अतिप्रवाह में कुछ धागा। इसके बाद, मैं आवश्यकतानुसार -viewWillAppear/-viewDidAppear पर मैन्युअल रूप से कॉल करता हूं।आईओएस: आईओएस 4.3 और 5.0

लेकिन, iOS 5.0 पर अपग्रेड करने के बाद, कुछ frisky UIView व्यवहार हुआ। अंत में मैंने पाया कि आईओएस 5, [superview addSubView:controller.view] में, -viewWillAppear/-viewDidAppear संदेश स्वचालित रूप से नियंत्रक उदाहरण पर भेज देगा, साथ ही साथ मैन्युअल रूप से कॉल करता है, प्रत्येक बार जब नियंत्रक कार्रवाई करता है तो दो डुप्लीकेट संदेश होते हैं।

और मैं भी एक ऐसी ही मुद्दा पाया: iOS 5 : -viewWillAppear is not called after dismissing the modal in iPad

अब, समस्या है, खोज सेब के दस्तावेजों के बाद, मैं नहीं किसी भी स्पष्ट रूप से इन मुद्दों के बारे diff के लिए दस्तावेज़ मिला। मुझे आश्चर्य है कि यह आईओएस 5.0 में एक गारंटीकृत जीवन जीवन चक्र व्यवहार है या नहीं।

क्या कोई भी इसी तरह के मुद्दों को ठीक करता है या इन अंतरों के बारे में कुछ दिशानिर्देश ढूंढता है। क्योंकि मैं अपने ऐप को 4.x & 5.x iOS दोनों में चलाने के लिए चाहता हूं।

+1

आप की खोज की है के रूप में, आईओएस 4 तथा iOS 5 के बीच परिवर्तन की केवल 10% को स्पष्ट रूप से दर्ज किया गया: वहाँ एक महान यहां इस मुद्दे को कवर ब्लॉग है। –

उत्तर

28

आईओएस 4 में आपको अपने दृश्य पदानुक्रम से दृश्य जोड़ने या हटाने के दौरान मैन्युअल रूप से -viewWillAppear, -viewWillDisappear आदि को कॉल करना पड़ा। ये iOS 5 में स्वचालित रूप से कहा जाता है, तो दृश्य जोड़ा गया या हटाया जा रहा है खिड़की पदानुक्रम से।

-(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { 
    return NO; 
} 

यह शायद सबसे आसान समाधान आप के रूप में के रूप में लंबा है: सौभाग्य से, iOS 5 UIViewController में एक विधि है कि आप व्यवहार कि यह कैसे आईओएस 4. के साथ काम किया बस अपने UIViewController में जोड़ने के लिए वापस लौटने को ओवरराइड कर सकते है आईओएस 4 और आईओएस दोनों का समर्थन कर रहे हैं 5. एक बार जब आप आईओएस 4 के लिए समर्थन छोड़ देते हैं तो आप विचारों को स्वैप करते समय नए दृष्टिकोण का उपयोग करने के लिए अपने कोड को संशोधित करने पर विचार कर सकते हैं।

संपादित 5 फरवरी 2012

जाहिर है इस समारोह बच्चे दृश्य नियंत्रक addChildViewController: पद्धति का उपयोग करके मुख्य दृश्य नियंत्रक के लिए जोड़ा जा आवश्यकता है। इस विधि iOS4 में मौजूद नहीं है, तो आप कुछ इस तरह करने की जरूरत है:

if ([self respondsToSelector:@selector(addChildViewController:)]) { 
    [self addChildViewController:childViewController]; 
    } 

जो कोई मुझे इस पर सुधारा के लिए धन्यवाद।

+0

धन्यवाद बहुत दोस्त !!!! –

+0

धन्यवाद, आईओएस 4 पर समस्या तय की गई है, लेकिन ios5 viewWillAppear पर दो बार कहा जाता है (मैन्युअल कॉल में से एक जिसे मैंने रखा है) सुनिश्चित नहीं है कि क्यों। – richy

+1

रिची .. यह अजीब बात है क्योंकि आईओएस 4 में इस विधि को नजरअंदाज कर दिया गया है और केवल आईओएस 5 में ही कहा जाता है। आप अपने परिणामों को दोबारा जांचना चाहेंगे। – chris

0

इस विधि यू पता है जो ओएस यू का उपयोग करें और हालत डाल अगर है तक कम 5.0 या अन्य एक

[[UIDevice currentDevice] systemVersion]

+0

मुझे पता है कि इस तरह से कुछ मदद करते हैं। और मैं इस तरह के अंतर के बारे में और जानना चाहता हूं। – KrzyCube

9

यह एक जवाब आप क्या चाहते हैं नहीं हो सकता है, लेकिन मुझे एक ही तरह की समस्या थी।

मेरे मामले, जब मैं एक subview, subview केवल iOS 5.0 नहीं आईओएस 4.x. में viewWillAppear प्राप्त किया गया था के रूप में एक और दृश्य नियंत्रक के दृश्य के लिए एक दृश्य नियंत्रक के दृश्य जोड़ा गया में

तो मैंने एक बुरा शर्त जोड़ा।

[self.view addSubview:self.viewController.view]; 
if ([[[UIDevice currentDevice] systemVersion] compare:@"5.0"] == NSOrderedAscending) { 
    [self.viewController viewWillAppear:animated]; 
} 

आईओएस 5.0, Apple provides a way to implement custom container view controllers like UINavigationController or UITabController से। मुझे लगता है कि यह परिवर्तन तब प्रभावित होता है जब ViewWillAppear को बुलाया जाता है।

यदि हम -[UIViewController addChildViewController:] का उपयोग करते हैं तो यह समस्या हल हो सकती है।

+0

मुझे नहीं लगता कि इसका ओएस संस्करण के साथ कुछ भी करना है। एपीआई वही बना हुआ है। निश्चित नियम हैं कि जब विज़िअपर/डिसप्लेयर कॉल किया जाएगा। http://stackoverflow.com/questions/131062/iphone-viewwillappear-not-firing – zakishaheen

+0

आपकी मदद के लिए बहुत बहुत धन्यवाद! :) –

2

यह आईओएस 5 व्यवहार है:
viewWillAppear, viewDidAppear, ... addSubView के बाद स्वचालित रूप से निष्पादित किया जाता है: आईओएस 5 के लिए।
तो आईओएस 5 के लिए आईओएस < 5.0 के लिए मैन्युअल रूप से उन विधियों को निष्पादित करने की आवश्यकता नहीं है।

ठीक हो सकता है:

if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { 
...execute viewWillAppear or other 
} 
0

view{Will,Did}Appear, view{Will,Did}Disappear पर देखें नियंत्रकों और नहीं देखा गया कार्य हैं। इन कार्यों को एसडीके द्वारा बुलाया जाता है जो दृश्य नियंत्रकों को प्रदान किया जाता है जो अन्य दृश्य नियंत्रकों का प्रबंधन करते हैं। UITabBarController, UINavigationBarController

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

5

एक से थोड़ा अधूरा ऊपर जवाब। मान लीजिए कि आपके पास 2 व्यू कंट्रोलर, कंट्रोलर ए और कंट्रोलरबी है।

ControllerA.view पहले से ही विंडो (यह माता पिता है) को जोड़ा गया है, और आप ControllerB.view ControllerA की एक subview के रूप में जोड़ना चाहते हैं।

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

उदाहरण:

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { 
    return NO; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.controllerB = [[ControllerB alloc] initWithNibName:@"ControllerB" bundle:nil]; 

    [self.view addSubview:self.controllerB.view]; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self.controllerB viewWillAppear:animated]; 
} 
viewWillAppear में

ControllerB NSLogging में:

- (void)viewWillAppear:(BOOL)animated 
{ 
    NSLog("@ControllerB will appear"); 
} 

यह iOS5 में परिणाम होगा ही नहीं NSLog संदेश दो बार प्रदर्शित। यानी आप स्वचालित रूप से फॉरवर्डएपियरेंस एंडरोटेशन मोड्स टू चिल्डव्यू कंट्रोलर को अनदेखा कर दिया गया है।

आदेश इसे ठीक करने के लिए, आपको controllerB नियंत्रक एक के एक बच्चे के रूप में जोड़ने की जरूरत है।

ControllerA की कक्षा में वापस

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.controllerB = [[ControllerB alloc] initWithNibName:@"ControllerB" bundle:nil]; 
    if ([self respondsToSelector:@selector(addChildViewController:)]) 
     [self addChildViewController:self.controllerB]; 

    [self.view addSubview:self.controllerB.view]; 
} 

अब यह काम होगा दोनों iOS4 और iOS5 में अपेक्षा के अनुरूप iOS संस्करण तार जाँच की भयानक हैक का सहारा, लेकिन इसके बजाय की जाँच कर के बिना समारोह के बाद हम कर रहे हैं उपलब्ध है।

उम्मीद है कि इससे मदद मिलती है।

0

सभी साक्ष्य की समीक्षा करने के बाद, मैं सबसे अच्छी बात करने के लिए देखा गया है कि इस ios 4/ios 5 बग से प्रभावित हैं के लिए उपयोग नहीं किया जाता है viewDidAppear आदि लगता है।इसके बजाय एक कस्टम क्लास (जैसे viewDidAppearCustom) बनाएं और इसे स्वयं कॉल करें। इस तरह आप गारंटी दे सकते हैं कि सेब फिर से एसडीके नहीं बदलेगा और आपको गड़बड़ कर देगा।

http://gamesfromwithin.com/view-controller-notification-changes-on-ios5

संबंधित मुद्दे