पता लगा रहा है कि 'बैक' बटन कब नेबार पर दबाया गया है


135

जब बैक बटन (पिछली स्क्रीन पर वापस आना, पैरेंट-व्यू पर लौटना) बटन को कुछ क्रियाओं को करने की आवश्यकता होती है, तो एक नेवबार पर दबाया जाता है।

स्क्रीन को गायब होने से पहले डेटा को रोकने और सहेजने के लिए कुछ विधि है जो मैं इवेंट को पकड़ने और कुछ क्रियाओं को आग लगाने के लिए लागू कर सकता हूं?




मैंने इसे इस तरह से यहाँ निर्णय लिया
तरास

जवाबों:


316

अद्यतन: कुछ टिप्पणियों के अनुसार, मूल उत्तर में समाधान iOS 8+ में कुछ निश्चित परिदृश्यों के तहत काम नहीं करता है। मैं यह सत्यापित नहीं कर सकता कि वास्तव में आगे के विवरण के बिना मामला है।

हालांकि आप के लिए उस स्थिति में एक विकल्प है। जब कोई व्यू नियंत्रक पॉप किया जा रहा है तब पता लगाना ओवरराइड करके संभव है willMove(toParentViewController:)। मूल विचार यह है कि जब एक दृश्य नियंत्रक पॉप किया जा रहा parentहै nil

अधिक विवरण के लिए "एक कंटेनर व्यू कंट्रोलर को लागू करना " देखें


IOS 5 के बाद से मैंने पाया है कि इस स्थिति से निपटने का सबसे आसान तरीका नई विधि का उपयोग करना है - (BOOL)isMovingFromParentViewController:

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];

  if (self.isMovingFromParentViewController) {
    // Do your stuff here
  }
}

- (BOOL)isMovingFromParentViewController समझ में आता है जब आप एक नेविगेशन स्टैक में नियंत्रकों को धक्का और पॉपिंग कर रहे हैं।

हालाँकि, यदि आप मोडल व्यू कंट्रोलर प्रस्तुत कर रहे हैं, तो आपको - (BOOL)isBeingDismissedइसके बजाय उपयोग करना चाहिए :

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];

  if (self.isBeingDismissed) {
    // Do your stuff here
  }
}

के रूप में में बताया गया है इस सवाल का , तो आप दोनों के गुण जोड़ सकता:

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];

  if (self.isMovingFromParentViewController || self.isBeingDismissed) {
    // Do your stuff here
  }
}

अन्य समाधान एक के अस्तित्व पर निर्भर करते हैं UINavigationBar। इसके बजाय मेरे दृष्टिकोण को अधिक पसंद करते हैं क्योंकि यह आवश्यक क्रियाओं को डिक्रिप्ट करता है कार्रवाई से प्रदर्शन करने के लिए जो घटना को ट्रिगर करता है, अर्थात बैक बटन दबाता है।


मुझे आप का जवाब पसंद है। लेकिन आपने 'self.isBeingDismissed' का उपयोग क्यों किया? मेरे मामले में, 'self.isBeingDismissed' में कथन लागू नहीं होते हैं।
रुतविज कोटेचा

3
self.isMovingFromParentViewControllerTRUE मान है जब मैं नेविगेशन स्टैक को प्रोग्रामिक रूप से उपयोग कर रहा हूं popToRootViewControllerAnimated- बिना बैक बटन पर किसी भी स्पर्श के। क्या मुझे आपका जवाब नीचा दिखाना चाहिए? (विषय कहता है "'बैक' बटन एक नेबर पर दबाया जाता है")
कास-काद

2
बहुत बढ़िया जवाब, बहुत बहुत धन्यवाद। स्विफ्ट में मैंने इस्तेमाल किया:override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) if isMovingFromParentViewController(){ println("back button pressed") } }
कैमिलो विसिनी

1
आपको इसे केवल तभी करना चाहिए -viewDidDisappear:क्योंकि यह संभव है कि आप -viewWillDisappear:बिना किसी के मिल जाएंगे -viewDidDisappear:(जैसे कि जब आप नेविगेशन कंट्रोलर आइटम को खारिज करने के लिए स्वाइप करना शुरू करते हैं और फिर उस स्वाइप को रद्द कर देते हैं।
हीथ बॉर्डर्स

3
ऐसा लगता है कि कोई विश्वसनीय समाधान नहीं है। उस समय काम किया जब मैंने पहली बार इसका इस्तेमाल किया था (यह iOS 10 था)। लेकिन अब मैंने गलती से इसे शांति से काम करना बंद कर दिया (iOS 11)। "WillMove (toParentViewController)" समाधान पर स्विच करना पड़ा।
विटाली

100

जबकि viewWillAppear()और viewDidDisappear() कर रहे हैं जब वापस बटन उपयोग किया जाता है कहा जाता है, वे भी अन्य समय में कहा जाता है। उस पर अधिक के लिए उत्तर का अंत देखें।

UIViewController.parent का उपयोग करना

जब वीसी को माता-पिता (नेवीकंट्रोलर) से हटा दिया जाता है तो willMoveToParentViewController(_:)ओआर की मदद से बैक बटन का पता लगाना बेहतर होता हैdidMoveToParentViewController()

यदि अभिभावक शून्य है, तो व्यू कंट्रोलर को नेविगेशन स्टैक से हटा दिया जाता है और खारिज कर दिया जाता है। यदि माता-पिता शून्य नहीं हैं, तो इसे स्टैक में जोड़ा जा रहा है और प्रस्तुत किया गया है।

// Objective-C
-(void)willMoveToParentViewController:(UIViewController *)parent {
     [super willMoveToParentViewController:parent];
    if (!parent){
       // The back button was pressed or interactive gesture used
    }
}


// Swift
override func willMove(toParent parent: UIViewController?) {
    super.willMove(toParent: parent)
    if parent == nil {
        // The back button was pressed or interactive gesture used
    }
}

बाहर स्वैप willMoveके लिए didMoveऔर जांच self.parent काम करने के लिए के बाद दृश्य नियंत्रक को खारिज कर दिया है।

बर्खास्तगी को रोक रहा है

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

var backButton : UIBarButtonItem!

override func viewDidLoad() {
    super.viewDidLoad()

     // Disable the swipe to make sure you get your chance to save
     self.navigationController?.interactivePopGestureRecognizer.enabled = false

     // Replace the default back button
    self.navigationItem.setHidesBackButton(true, animated: false)
    self.backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "goBack")
    self.navigationItem.leftBarButtonItem = backButton
}

// Then handle the button selection
func goBack() {
    // Here we just remove the back button, you could also disabled it or better yet show an activityIndicator
    self.navigationItem.leftBarButtonItem = nil
    someData.saveInBackground { (success, error) -> Void in
        if success {
            self.navigationController?.popViewControllerAnimated(true)
            // Don't forget to re-enable the interactive gesture
            self.navigationController?.interactivePopGestureRecognizer.enabled = true
        }
        else {
            self.navigationItem.leftBarButtonItem = self.backButton
            // Handle the error
        }
    }
}


अधिक देखने पर / दिखाई देगा

यदि आपको viewWillAppear viewDidDisappearसमस्या नहीं मिली , तो आइए एक उदाहरण के माध्यम से चलते हैं। कहते हैं कि आपके पास तीन दृश्य नियंत्रक हैं:

  1. ListVC: चीजों का एक टेबल व्यू
  2. DetailVC: एक चीज़ के बारे में विवरण
  3. SettingsVC: एक चीज के लिए कुछ विकल्प

के detailVCरूप में आप से और वापस करने के listVCलिए जाने पर कॉल का पालन करेंsettingsVClistVC

सूची> डिटेल (पुश डिटेलवी) Detail.viewDidAppear<-
डिटेल> सेटिंग्स (पुश सेटिंग्सवीसी) Detail.viewDidDisappear<- गायब दिखाई दें

और जैसा कि हम वापस जाते हैं ...
सेटिंग्स> विवरण (पॉप सेटिंग्सवीसी) Detail.viewDidAppear<-
विवरण> सूची (पॉप विवरणवीवीसी) Detail.viewDidDisappear<- गायब दिखाई दें

नोटिस जो viewDidDisappearकई बार कहा जाता है, न केवल जब वापस जा रहा है, बल्कि आगे बढ़ने पर भी। एक त्वरित ऑपरेशन के लिए जिसे वांछित किया जा सकता है, लेकिन अधिक जटिल ऑपरेशन के लिए जैसे नेटवर्क कॉल को सहेजना है, यह नहीं हो सकता है।


didMoveToParantViewController:जब दृश्य अब दिखाई नहीं दे रहा है तो बस एक नोट, उपयोगकर्ता को काम करने के लिए। इंटरएक्टिवसुत्र के साथ iOS7 के लिए मददगार
WCByrne

didMoveToParentViewController * वहाँ एक टाइपो है
9-30-50 पर thewormsterror

[सुपर willMoveToParentViewController: जनक] फोन करने के लिए मत भूलना!
स्कूटीबी

2
मूल पैरामीटर nil है जब आप मूल दृश्य नियंत्रक को पॉपिंग कर रहे हैं, और जब यह विधि दिखाई देती है तो गैर-शून्य दिखाई जाती है। आप उस तथ्य का उपयोग केवल एक कार्रवाई करने के लिए कर सकते हैं जब बैक बटन दबाया जाता है, और दृश्य में पहुंचने पर नहीं। आखिरकार, मूल प्रश्न था। :)
माइक

1
यह प्रोग्रामिक रूप से उपयोग करते समय भी कहा जाता है _ = self.navigationController?.popViewController(animated: true), इसलिए इसे सिर्फ बैक बटन प्रेस पर नहीं बुलाया जाता है। मैं एक ऐसे कॉल की तलाश में हूं जो केवल तभी काम करता है जब बैक को दबाया जाता है।
एथन एलन

16

पहला तरीका

- (void)didMoveToParentViewController:(UIViewController *)parent
{
    if (![parent isEqual:self.parentViewController]) {
         NSLog(@"Back pressed");
    }
}

दूसरी विधि

-(void) viewWillDisappear:(BOOL)animated {
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
       // back button was pressed.  We know this is true because self is no longer
       // in the navigation stack.  
    }
    [super viewWillDisappear:animated];
}

1
दूसरी विधि केवल वही थी जो मेरे लिए काम करती थी। मेरे विचार प्रस्तुत किए जाने पर पहली विधि को भी कहा गया, जो मेरे उपयोग के मामले के लिए स्वीकार्य नहीं थी।
marcshilling

10

जो दावा करते हैं कि यह गलत नहीं है:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if self.isMovingFromParent {
        print("we are being popped")
    }
}

यह ठीक काम करता है। तो क्या व्यापक मिथक पैदा कर रहा है कि यह नहीं है?

समस्या एक अलग पद्धति के गलत कार्यान्वयन के कारण प्रतीत होती है , अर्थात् willMove(toParent:)कॉल को भूल जाना super

यदि आप willMove(toParent:)बिना बुलाए लागू करते हैं super, तो self.isMovingFromParentहोगा falseऔर इसका उपयोग viewWillDisappearविफल होता दिखाई देगा। यह विफल नहीं हुआ; आपको इसे तोड़ा।

नोट: वास्तविक समस्या आमतौर पर दूसरे व्यू कंट्रोलर का पता लगाती है कि पहला व्यू कंट्रोलर पॉप अप हुआ था। कृपया यहां और अधिक सामान्य चर्चा भी देखें: यूनिफाइड यूविविकंट्रोलर "फ्रंटएस्ट" बन गया?

EDIT A टिप्पणी बताती है कि यह इसके viewDidDisappearबजाय होना चाहिए viewWillDisappear


जब बैक बटन टैप किया जाता है, तो इस कोड को निष्पादित किया जाता है, लेकिन वीसी द्वारा प्रोग्राम किए जाने के बाद भी इसे निष्पादित किया जाता है।
बायोमाइकर

@ निओमीकर ज़रूर, लेकिन यह भी अन्य दृष्टिकोणों का सच होगा। पॉपिंग पॉपिंग है। सवाल यह है कि जब आप प्रोग्राम पॉप नहीं करते तो पॉप का पता कैसे लगाया जाता है । यदि आप प्रोग्रामेटिक रूप से पॉप करते हैं तो आप पहले से ही जानते हैं कि आप पॉपिंग कर रहे हैं इसलिए पता लगाने के लिए कुछ नहीं है।
मैट

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

1
दुर्भाग्य से यह trueइंटरेक्टिव स्वाइप पॉप जेस्चर के लिए रिटर्न - व्यू कंट्रोलर के बाएं किनारे से - भले ही स्वाइप ने इसे पूरी तरह से पॉप न किया हो। इसलिए इसे जांचने के बजाय willDisappear, didDisappearकामों में ऐसा करना चाहिए ।
बदनगनेश

1
@badhanganesh धन्यवाद, उस जानकारी को शामिल करने के लिए संपादित उत्तर।
मैट

9

मैं दो दिनों से इस समस्या से खेल रहा हूं (या लड़ रहा हूं)। IMO सबसे अच्छा तरीका है एक विस्तार वर्ग और एक प्रोटोकॉल बनाना, जैसे:

@protocol UINavigationControllerBackButtonDelegate <NSObject>
/**
 * Indicates that the back button was pressed.
 * If this message is implemented the pop logic must be manually handled.
 */
- (void)backButtonPressed;
@end

@interface UINavigationController(BackButtonHandler)
@end

@implementation UINavigationController(BackButtonHandler)
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
    UIViewController *topViewController = self.topViewController;
    BOOL wasBackButtonClicked = topViewController.navigationItem == item;
    SEL backButtonPressedSel = @selector(backButtonPressed);
    if (wasBackButtonClicked && [topViewController respondsToSelector:backButtonPressedSel]) {
        [topViewController performSelector:backButtonPressedSel];
        return NO;
    }
    else {
        [self popViewControllerAnimated:YES];
        return YES;
    }
}
@end

यह काम करता है क्योंकि हर बार जब कोई व्यू कंट्रोलर पॉप अप UINavigationControllerहोता है तो कॉल आएगा navigationBar:shouldPopItem:। वहाँ हम पता लगाते हैं कि वापस दबाया गया था या नहीं (कोई अन्य बटन)। केवल एक चीज जो आपको करनी है, वह दृश्य नियंत्रक में प्रोटोकॉल को लागू करना है जहां वापस दबाया जाता है।

backButtonPressedSelअगर सब कुछ ठीक है, तो व्यू कंट्रोलर को मैन्युअल रूप से पॉप-अप करें ।

यदि आप पहले से ही उपवर्गित कर चुके हैं UINavigationViewControllerऔर लागू navigationBar:shouldPopItem:नहीं किया है, तो यह चिंता का विषय नहीं होगा।

तुम भी वापस इशारे को निष्क्रिय करने में रुचि हो सकती है।

if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

1
यह जवाब मेरे लिए लगभग पूरा हो गया था, सिवाय इसके कि मैंने पाया कि 2 व्यू कॉन्ट्रॉलर्स अक्सर पॉपप होते होंगे। रिटर्निंग यस कॉलिंग विधि को पॉप कॉल करने का कारण बनता है, इसलिए पॉपिंग कॉलिंग का अर्थ है कि 2 व्यूकंट्रोलर पॉप हो जाएंगे। अधिक डाइट के लिए एक और प्रश्न पर यह उत्तर देखें (एक बहुत अच्छा उत्तर जो अधिक उत्थान के योग्य है): stackoverflow.com/a/26084150/978083
जेसन रिज

अच्छी बात, मेरा विवरण उस तथ्य के बारे में स्पष्ट नहीं था। "सब कुछ ठीक है तो व्यू कंट्रोलर को पॉप्युलेट करना याद रखें" यह केवल "NO" की स्थिति के लिए है, अन्यथा प्रवाह सामान्य पॉप है।
7ynk3r

1
"और 'शाखा के लिए, सुपर कार्यान्वयन को कॉल करना बेहतर है यदि आप अपने आप को पॉप को संभालना नहीं चाहते हैं और इसे जो कुछ भी ठीक लगता है उसे वापस करने दें, जो कि ज्यादातर हाँ है, लेकिन यह भी पॉप का ख्याल रखता है और ठीक से शेवरॉन को एनिमेट करता है ।
बेन सिंक्लेयर

9

यह मेरे लिए iOS 9.3.x में स्विफ्ट के साथ काम करता है:

override func didMoveToParentViewController(parent: UIViewController?) {
    super.didMoveToParentViewController(parent)

    if parent == self.navigationController?.parentViewController {
        print("Back tapped")
    }
}

यहां अन्य समाधानों के विपरीत, यह अप्रत्याशित रूप से ट्रिगर नहीं होता है।


इसके बजाय विलो का उपयोग करना बेहतर है
यूजीन

4

रिकॉर्ड के लिए, मुझे लगता है कि यह वही है जो वह खोज रहा था ...

    UIBarButtonItem *l_backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRewind target:self action:@selector(backToRootView:)];

    self.navigationItem.leftBarButtonItem = l_backButton;


    - (void) backToRootView:(id)sender {

        // Perform some custom code

        [self.navigationController popToRootViewControllerAnimated:YES];
    }

1
धन्यवाद पॉल, यह समाधान काफी सरल है। दुर्भाग्य से, आइकन अलग है। यह "रिवाइंड" आइकन है, न कि बैक आइकन। हो सकता है कि बैक आइकन का उपयोग करने का एक तरीका हो ...
फेरन मेनलिच

2

जैसा कि purrrminatorकहा गया है, द्वारा उत्तर elitalonपूरी तरह से सही नहीं है, क्योंकि your stuffप्रोग्रामर को पॉपप करने पर भी निष्पादित किया जाएगा।

अब तक मैंने जो समाधान पाया है वह बहुत अच्छा नहीं है, लेकिन यह मेरे लिए काम करता है। क्या elitalonकहा, इसके अलावा , मैं यह भी जाँचता हूँ कि मैं प्रोग्रामिंग पॉपिंग कर रहा हूँ या नहीं:

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];

  if ((self.isMovingFromParentViewController || self.isBeingDismissed)
      && !self.isPoppingProgrammatically) {
    // Do your stuff here
  }
}

आपको उस प्रॉपर्टी को अपने कंट्रोलर के साथ जोड़ना होगा और प्रोग्रामेटिक रूप से पॉप करने से पहले इसे YES में सेट करना होगा:

self.isPoppingProgrammatically = YES;
[self.navigationController popViewControllerAnimated:YES];

आपकी सहायताके लिए धन्यवाद!


2

UINavigationController प्रतिनिधि विधियों का उपयोग करने का सबसे अच्छा तरीका है

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated

इसका उपयोग करके आप जान सकते हैं कि नियंत्रक UINavigationController क्या दिखा रहा है।

if ([viewController isKindOfClass:[HomeController class]]) {
    NSLog(@"Show home controller");
}

इसे सही उत्तर के रूप में चिह्नित किया जाना चाहिए! शायद लोगों को याद दिलाने के लिए एक और लाइन जोड़ना चाहते हैं -> self.navigationController.delegate = self;
माइक क्रिचले

2

मैंने बाईं ओर नेविगेशनबार में एक UIControl जोड़कर इस समस्या को हल किया है।

UIControl *leftBarItemControl = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, 90, 44)];
[leftBarItemControl addTarget:self action:@selector(onLeftItemClick:) forControlEvents:UIControlEventTouchUpInside];
self.leftItemControl = leftBarItemControl;
[self.navigationController.navigationBar addSubview:leftBarItemControl];
[self.navigationController.navigationBar bringSubviewToFront:leftBarItemControl];

और आपको यह देखने के लिए याद रखना होगा कि जब दृश्य गायब हो जाएगा:

- (void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if (self.leftItemControl) {
        [self.leftItemControl removeFromSuperview];
    }    
}

बस इतना ही!


2

आप बैक बटन कॉलबैक का उपयोग कर सकते हैं, जैसे:

- (BOOL) navigationShouldPopOnBackButton
{
    [self backAction];
    return NO;
}

- (void) backAction {
    // your code goes here
    // show confirmation alert, for example
    // ...
}

स्विफ्ट संस्करण के लिए आप वैश्विक दायरे में कुछ कर सकते हैं

extension UIViewController {
     @objc func navigationShouldPopOnBackButton() -> Bool {
     return true
    }
}

extension UINavigationController: UINavigationBarDelegate {
     public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
          return self.topViewController?.navigationShouldPopOnBackButton() ?? true
    }
}

नीचे दिए गए एक दृश्यदर्शी में, जहाँ आप बैक बटन क्रिया को नियंत्रित करना चाहते हैं:

override func navigationShouldPopOnBackButton() -> Bool {
    self.backAction()//Your action you want to perform.

    return true
}

1
पता नहीं क्यों किसी ने वोट नहीं दिया। यह अब तक का सबसे अच्छा जवाब है।
अविनाश

@ अविनाश कहाँ navigationShouldPopOnBackButtonसे आता है? यह सार्वजनिक एपीआई का हिस्सा नहीं है।
एलिटालोन

@elitalon क्षमा करें, यह आधा उत्तर था। मैंने सोचा था कि शेष संदर्भ प्रश्न में था। वैसे भी अब जवाब अपडेट किया है
अविनाश

1

जैसा कि Coli88 ने कहा, आपको UINavigationBarDelegate प्रोटोकॉल की जांच करनी चाहिए।

अधिक सामान्य तरीके से, आप - (void)viewWillDisapear:(BOOL)animatedकस्टम काम करने के लिए भी उपयोग कर सकते हैं जब दृश्य दृश्य नियंत्रक द्वारा बनाए रखा गया दृश्य गायब होने वाला हो। दुर्भाग्य से, यह कवर और पॉप मामलों को परेशान करेगा।


1

UINavigationController के साथ स्विफ्ट के लिए:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    if self.navigationController?.topViewController != self {
        print("back button tapped")
    }
}

1

7ynk3r का उत्तर वास्तव में मेरे द्वारा उपयोग किए जाने के करीब था, लेकिन इसके लिए कुछ ट्विक्स की आवश्यकता थी:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {

    UIViewController *topViewController = self.topViewController;
    BOOL wasBackButtonClicked = topViewController.navigationItem == item;

    if (wasBackButtonClicked) {
        if ([topViewController respondsToSelector:@selector(navBackButtonPressed)]) {
            // if user did press back on the view controller where you handle the navBackButtonPressed
            [topViewController performSelector:@selector(navBackButtonPressed)];
            return NO;
        } else {
            // if user did press back but you are not on the view controller that can handle the navBackButtonPressed
            [self popViewControllerAnimated:YES];
            return YES;
        }
    } else {
        // when you call popViewController programmatically you do not want to pop it twice
        return YES;
    }
}


0

self.navigationController.isMovingFromParentViewController iOS8 और 9 उपयोग पर अब काम नहीं कर रहा है:

-(void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if (self.navigationController.topViewController != self)
    {
        // Is Popping
    }
}

-1

(SWIFT)

अंतिम रूप से पाया गया समाधान .. जिस विधि की हम तलाश कर रहे थे, वह है "willShowViewController" जो कि UINavadController की प्रतिनिधि विधि है

//IMPORT UINavigationControllerDelegate !!
class PushedController: UIViewController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        //set delegate to current class (self)
        navigationController?.delegate = self
    }

    func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        //MyViewController shoud be the name of your parent Class
        if var myViewController = viewController as? MyViewController {
            //YOUR STUFF
        }
    }
}

1
इस दृष्टिकोण के साथ परेशानी यह है कि यह जोड़े MyViewControllerको PushedController
clozach
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.