2009-06-05 16 views
21

मेरे पास एक टैबबार नियंत्रक है जिसमें दो टैब हैं, जिनमें से पहले नेविगेटर नियंत्रक का एक उदाहरण है। नेविगेटर कंट्रोलर को एक कस्टम व्यू कंट्रोलर "peersViewController" के साथ शुरू किया गया है जो सभी नेटवर्क सहकर्मियों को तालिका तालिका में सूचीबद्ध करता है। एक सहकर्मी का चयन करने पर, "FilesListViewController" का एक उदाहरण (जो c: \ निर्देशिका में फ़ाइलों को सूचीबद्ध करता है) नेविगेशन नियंत्रक स्टैक में धकेल दिया जाता है।UINavigationController popToRootViewController, और उसके बाद तुरंत एक नया दृश्य

इन फ़ाइलों में लिस्ट व्यू कंट्रोलर मेरे पास दस्तावेज़ निर्देशिका कहने के लिए नेविगेट करने के लिए एक बटन है। ऐसा करने के लिए मैं एक gotoDirectory कॉल करने के लिए इंटरफ़ेस वायर्ड था: (NSString *) rootViewController में पथ विधि:

- (void)gotoDirectory:(NSString*)path { 
    [[self navigationController] popToRootViewControllerAnimated:YES]; 
    NSArray *files = [self getFilesFromPeerAtPath:path]; 
    FilesListViewController *filesVC = [[FilesListViewController alloc] initWithFiles:files]; 
    [[self navigationController] pushViewController:filesVC animated:YES]; 
    [filesVC release]; 
} 

हालांकि, जब मैं प्रेस कि बटन, navigationController रूट दृश्य नियंत्रक करने के लिए मेरे विचार पॉप था , लेकिन तब FilesListViewController जो मैंने तुरंत चालू नहीं किया था। लॉग से, मुझे पता है कि कस्टम initWithFiles विधि वास्तव में बुलाया गया था और फ़ाइल नाम प्राप्त करने के लिए नेटवर्क सामग्री हुई थी।

इसके बारे में कुछ और खराब है। मैंने दूसरे टैब पर क्लिक करने की कोशिश की और फिर पहले टैब पर वापस क्लिक करें, और हुला! मुझे आवश्यक फाइल नाम हैं। ऐसा लगता है कि डेटा और फ़ाइलों की तरह ListViewController को वास्तव में नेविगेटर नियंत्रक स्टैक में धकेल दिया गया था, लेकिन डिस्प्ले को रीफ्रेश नहीं किया गया था लेकिन rootViewController (peersViewController) की स्क्रीन पर फंस गया था।

क्या मैं कुछ गलत कर रहा हूं?

--बेन।

- प्रश्न पोस्ट करने के 15 मिनट बाद संपादित किया गया। मुझे एक कामकाज मिल गया, लेकिन यह मुझे परेशान करता है कि पॉप और फिर धक्का काम नहीं करता है।

- (void)gotoDirectory:(NSString*)path { 
    PeersListViewController *rootViewController = (PeersListViewController*)[[[self navigationController] viewControllers] objectAtIndex:0]; 
    [[self navigationController] setViewControllers:[NSArray arrayWithObject:rootViewController]]; 
    FilesListViewController *filesVC = [[FilesListViewController alloc] initWithFiles:files]; 
    [[self navigationController] pushViewController:filesVC animated:YES]; 
    [filesVC release]; 
} 

यह navigationController की तरह प्रतीत नहीं होता है इस तरह से उन्हें धोखा दिया जाना चाहिए, और मैं शायद सब viewControllers कि मूल ढेर में थे जारी करने के लिए होगा। हालांकि यह आईफोन 3.0 सिम्युलेटर पर काम करता है।

यदि मैं इस कोड का उपयोग कर रहा हूं, तो स्मृति रिलीज को कैसे संभाला जाना चाहिए? क्या मुझे व्यू कंट्रोलर के मूल एनएसएआरएआरई मिलना चाहिए और सबकुछ छोड़ना चाहिए?

उत्तर

10

मुझे एक बहुत ही समस्या मिली (लेकिन टैब का उपयोग किए बिना)।

मुझे तीन दृश्य नियंत्रक: मुख्य (रूट), रूप और परिणाम मिला। जब UINavigationController ढेर

है "मुख्य -> ​​परिणाम"

एक btnClick मैं एक popToRootViewControllerAnimated तो formViewCtrl की एक धक्का कर पर

। क्रम में के लिए

"मुख्य -> ​​फार्म"

नेवबार शीर्षक और वापस बटन लेबल सही हैं और formViewCtrl की घटना कहा जाता है। लेकिन, मुझे अभी भी मुख्य दृश्य दिखाई देता है।

यहाँ मेरी "समाधान"

कुछ परीक्षण करने के बाद है, मुझे पता चला है कि एनीमेशन के बिना इस काम ठीक rootViwCtrl पर जाने के लिए। तो मैं viewCtrl को धक्का देने के लिए केवल एनीमेशन का उपयोग करता हूं।

आईफोन 3।0, डिवाइस & सिम्युलेटर पर मिली समस्या।

अगर मुझे कुछ नया मिला, तो मैं अपनी पोस्ट अपडेट/टिप्पणी करूंगा।

+2

हाँ, आप एनीमेशन के बिना पॉप (इतना है कि यह सही दूर होता है) और फिर एनीमेशन के साथ पुश करने के लिए की जरूरत है। यदि आप दो एनीमेशन परिवर्तनों को एक साथ करने की कोशिश करते हैं (जो पूरा करने में समय लगता है) दृश्य खराब स्थिति में मिलेगा। – Jason

+0

जैसा कि वर्णन किया गया है, यह मेरे लिए काम नहीं करता है। मुझे लगता है कि यह स्टैक परिवर्तनों पर एक समय मुद्दा है (ऐप्पल का एनीमेशन कोड बहुत नाजुक है, इसे खराब तरीके से लागू किया गया है) - यह तकनीक स्क्रीन पर और कितनी है, इस पर निर्भर करती है या नहीं। – Adam

1

मुझे एक कामकाज मिला लेकिन मैं यह नहीं समझा सकता कि यह क्यों काम कर रहा है: 1. पहले आवश्यक नियंत्रक को दबाएं। 2. फिर उस व्यक्ति को पॉप करें जिसे आप चाहते हैं।

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

सादर, Vesko कोलेव

+0

यह वास्तव में काम नहीं करना चाहिए। लेकिन यह करता है। 3.0 में, मैंने पाया है कि क्लासिक दृष्टिकोण (दृश्य नियंत्रक सरणी को सीधे जोड़ना) हमेशा अपेक्षित काम नहीं करता है, इसलिए मैं इसके बजाय इस कार्यवाही की कोशिश कर रहा हूं। – Adam

76

समस्या और इस मुद्दे का हल वास्तव में बहुत सरल है।

कॉलिंग [self.navigationController popToRootViewControllerAnimated:YES]self.navigationControllernil पर सेट करता है। जब आप बाद में [self.navigationController pushViewController:someOtherViewController] पर कॉल करते हैं तो आप प्रभावी रूप से nil पर एक संदेश भेज रहे हैं, जो कुछ भी नहीं करता है।

वैकल्पिक हल के लिए, बस navigationController के लिए एक स्थानीय संदर्भ की स्थापना की और इसके बजाय उसका उपयोग:

UINavigationController * navigationController = self.navigationController; 
[navigationController popToRootViewControllerAnimated:NO]; 
[navigationController pushViewController:someOtherViewController animated:YES]; 

के रूप में जेसन ने कहा, popToRootViewController सही ढंग से काम करने के लिए इस के लिए एनीमेशन के बिना किया जाना चाहिए।

धन्यवाद इस बिंदु को इंगित करने के लिए jpimbert on the Apple forums पर जाएं।

+0

यह मेरे लिए काम किया !!! बहुत बहुत धन्यवाद ... +1 निक के लिए! – necixy

+1

मेरी इच्छा है कि मैं इसे एक से अधिक बार वोट दे सकता हूं! बहुत बढ़िया जवाब। – akpb

+0

सही समाधान! –

1

निक स्ट्रीट का उत्तर बहुत अच्छा काम करता है यदि आप popToRootViewController करना चाहते हैं और बाद में एक और वीसी दबाएं।

VC1 -> VC2 -> VC3: VC3 => VC2, तो VC1, यहाँ ठीक से वापस बटन हिट

हालांकि, जब VC1 धक्का VC2, जो बारी में VC3 धक्का, तो VC1 के लिए वापस जा VC3 से सीधे रूप में कामना काम नहीं करता है:

मैं VC3 के -(void)viewWillDisappear:(BOOL)animated में क्रियान्वित किया है:

-(void)viewWillDisappear:(BOOL)animated{ 

    ... 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
} 

मैं भी "वापस" बटन, एक ही परिणाम में इसे लागू करने की कोशिश की: से पीछे बटन दबाने पर वीसी 3 वीसी 1 पर वापस जाने के लिए: यह टूट जाता है। वास्तविक वीसी वीसी 1 है, लेकिन नेविगेशन बार अभी भी वीसी 2 है। अन्य संयोजनों के साथ खेलना, मुझे वीसी 2 पर वीसी 1 का एनवीबार मिलता है। पूर्णतः बिगड़ा।

लोडा ने समय के बारे में कुछ बताया। मुझे लगता है कि यह मुख्य मुद्दा है। मैं कुछ चीजें की कोशिश की है, तो शायद मैं यहाँ कुछ लाभ नहीं ले पा रही है, लेकिन यह है कि क्या मेरे लिए काम किया है, पिछले पर है:

VC3 में:

-(void)viewWillDisappear:(BOOL)animated { 

    [super viewWillDisappear:animated]; 
    // notify VC2 
    [[NSNotificationCenter defaultCenter] postNotificationName:backFromV3 object:self]; 
} 

VC2 में:

-(void)viewDidLoad { 

    ... 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(backFromV3) 
               name:@"BackFromV3" 
               object:nil]; 
} 

-(void)backFromV3{ 
    [NSTimer scheduledTimerWithTimeInterval:0.5 
           target:self 
           selector:@selector(backToRootViewController) 
           userInfo:nil 
           repeats:NO]; 
} 

-(void)backToVC1 { 
    self.navigationItem.rightBarButtonItem = nil; 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
} 

बेशक, आवश्यक सफाई करें।

टाइमर यहां महत्वपूर्ण है। यदि 0, तो यह टूट जाता है। 0।5 ठीक लगता है।

वह मेरे लिए पूरी तरह से काम करता है। थोड़ा भारी, लेकिन मैं कुछ भी नहीं ढूंढ पाया जो चाल करता है।

1

आप वास्तव में "वापस जाएं" एनीमेशन, मूल रूप से जब तक के बाद पॉप एनीमेशन पूरा हो गया है धक्का एनीमेशन में देरी से "आगे जाओ" एनीमेशन के बाद रख सकते हैं। यहां एक उदाहरण दिया गया है:

(नोट: मेरे पास मेरे एपडिलेगेट में "ट्रांजिशन टू" नामक एक एनएसएसटींग वैरिएबल है जिसे प्रारंभ में @ "" पर सेट किया गया है) ... सबसे पहले, उस वैरिएबल को एनएसएसटींग पर सेट करें जिसे आप बाद में पहचान सकते हैं। उसके बाद, आप एक अच्छा स्क्रीन संक्रमण वापस जड़ को देने के लिए नियंत्रक पॉप:

-(void)viewDidAppear:(BOOL)animated 
{ 
    AppDelegate *appDelegate =(AppDelegate*) [UIApplication sharedApplication].delegate; 
    if([appDelegate.transitionTo isEqualToString:@"Another"]) 
    { 
     [self transitionToAnotherView]; 
     appDelegate.transitionTo = @""; 
    } 
} 

-(void)transitionToAnotherView 
{ 
    // Create and push new view controller here 
    AnotherViewController *controller = [[AnotherViewController alloc] init]; 

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStyleBordered target:nil action:nil]; 
    [self.navigationItem setBackBarButtonItem:backButton]; 

    [[self navigationController] pushViewController:controller animated:YES]; 
} 

तो बुनियादी तौर पर, रूट करने के लिए पॉप: फिर

appDelegate.transitionTo = @"Another"; 
[detailNavigationController popToRootViewControllerAnimated:YES]; 

rootviewcontroller की कक्षा के अंदर, viewDidAppear विधि का उपयोग करें। .. जब संक्रमण "viewDidAppear" पर समाप्त होता है ... फिर अगला दृश्य दबाएं। मैं आपको यह बताने के लिए एक चर रखने के लिए हुआ कि आप किस दृश्य को बदलना चाहते हैं (जिसका मतलब है कि इस स्क्रीन पर रहने के मामले में संक्रमण नहीं करना है)।

3

मुझे लगता है कि रूट में पॉपिंग और फिर एक नई ViewController धकेलने के बारे में यह सवाल बहुत प्रचलित है, और इस पोस्ट में बहुत कुछ देखा जाता है, तो मैं अन्य नए लोगों को मदद करने के लिए मेरी बिट जोड़ना चाहते थे, खासकर उन लोगों Xcode का उपयोग कर 4 और एक स्टोरीबोर्ड।

Xcode 4 में, आप एक स्टोरीबोर्ड है। आइए मान लें कि आपके पास इन व्यू कंट्रोलर हैं: होम व्यू कंट्रोलर, फर्स्टपेज व्यू कंट्रोलर, सेकेंड पेज व्यू कंट्रोलर। यूटिलिटी फलक-> विशेषता निरीक्षक पर जाकर उनमें से प्रत्येक पर क्लिक करना और उनके पहचानकर्ताओं को नाम देना सुनिश्चित करें। हम कहेंगे कि उनका नाम घर, पहला और दूसरा नाम है।

आप घर कर रहे हैं, तो आप जाना सबसे पहले, तो आप दूसरे के पास जाकर वापस घर में जाने के लिए वापस जाएं बटन दबाएं करने में सक्षम हो करने में सक्षम होना चाहते हैं। ऐसा करने के लिए, आप अपना कोड FirstPageViewController में बदलना चाहते हैं।

उदाहरण पर विस्तार करने के लिए, स्टोरीबोर्ड में FirstPageViewController में एक बटन हैं। Ctrl- उस बटन को FirstPageViewController.m में खींचें। वहाँ में, निम्न कोड वांछित परिणाम प्राप्त होगा:

// Remember to add #import "SecondPageViewController.h" at the top 
    SecondPageViewController *secondView = [self.storyboard instantiateViewContorllerWithIdentifier:@"Second"]; 
    UINavigationController *navigationController = self.navigationController; 
    NSArray *array = [navigationController viewControllers]; 
    // [array objectAtIndex:0] is the root view controller 
    NSArray *viewControllersStack = [NSArray arrayWithObjects:[array objectAtIndex:0], secondView, nil]; 
    [navigationController setViewControllers:viewControllersStack animated:YES]; 

मूल रूप से, आप दृश्य नियंत्रक हथियाने कर रहे हैं, आप चाहते हैं क्रम में एक ढेर में उन्हें व्यवस्था करने, और फिर नेविगेशन नियंत्रक उपयोग उस के लिए ढेर होने पथ प्रदर्शन। यह धक्का और पॉपिंग का एक विकल्प है।

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