viewWillDisappear:تحديد ما إذا كان عرض وحدة تحكم يتم برزت أو يظهر الفرعية تحكم عرض

StackOverflow https://stackoverflow.com/questions/1816614

سؤال

أنا تكافح من أجل إيجاد حل جيد لهذه المشكلة.في عرض المراقب المالي -viewWillDisappear: طريقة, أنا بحاجة إلى إيجاد طريقة لتحديد ما إذا كان ذلك بسبب عرض وحدة تحكم يتم دفعها على وحدة تحكم الملاحة المكدس ، أو ما إذا كان عرض وحدة تحكم تختفي لأنه قد برزت.

في هذه اللحظة أنا وضع الأعلام مثل isShowingChildViewController ولكن الأمر يزداد معقدة إلى حد ما.الطريقة الوحيدة أعتقد أنني يمكن الكشف عن ذلك في -dealloc الأسلوب.

هل كانت مفيدة؟

المحلول

ويمكنك استخدام ما يلي.

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  NSArray *viewControllers = self.navigationController.viewControllers;
  if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
    // View is disappearing because a new view controller was pushed onto the stack
    NSLog(@"New view controller was pushed");
  } else if ([viewControllers indexOfObject:self] == NSNotFound) {
    // View is disappearing because it was popped from the stack
    NSLog(@"View controller was popped");
  }
}

وهذا هو، بطبيعة الحال، ممكن لأن كومة رأي تحكم في UINavigationController في (يتعرض من خلال الخاصية viewControllers) تم تحديث في الوقت الذي يسمى viewWillDisappear.

نصائح أخرى

وأعتقد أن أسهل طريقة هي:

 - (void)viewWillDisappear:(BOOL)animated
{
    if ([self isMovingFromParentViewController])
    {
        NSLog(@"View controller was popped");
    }
    else
    {
        NSLog(@"New view controller was pushed");
    }
    [super viewWillDisappear:animated];
}

وسويفت:

override func viewWillDisappear(animated: Bool)
{
    if isMovingFromParentViewController
    {
        print("View controller was popped")
    }
    else
    {
        print("New view controller was pushed")
    }
    super.viewWillDisappear(animated)
}

ومن الوثائق أبل في UIViewController.h:

<اقتباس فقرة>   

و"هذه الطرق الأربعة يمكن استخدامها في مظهر وحدة تحكم طريقة العرض   الاسترجاعات لتحديد ما إذا كان يتم تقديمه، رفض، أو إضافتها   أو إزالة وحدة تحكم رأي الطفل. على سبيل المثال، وحدة تحكم الرأي   يمكن معرفة ما اذا كان يختفي لأنه تم صرف النظر عنه أو برزت   عن طريق طرح نفسها في viewWillDisappear لها: طريقة عن طريق فحص   التعبير ([النفس isBeingDismissed] || [النفس   isMovingFromParentViewController]). "

     

و- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);

     

و- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);

     

و- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);

     

و- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);

وهكذا نعم، والطريقة الوحيدة الموثقة للقيام بذلك هي على النحو التالي:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if ([self isBeingDismissed] || [self isMovingFromParentViewController]) {
    }
}

وسويفت 3 النسخة:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if self.isBeingDismissed || self.isMovingFromParentViewController { 
    }
}

إذا كنت ترغب فقط في معرفة ما إذا كانت وجهة نظركم هو الحصول على انتشرت، لقد اكتشفت للتو أن self.navigationController هو nil في viewDidDisappear، عندما يتم إزالته من كومة من أجهزة التحكم. ذلك أن اختبار بديل بسيط.

و(هذا اكتشفت بعد محاولة كل أنواع من التشويهات الأخرى. أنا مندهش ليس هناك بروتوكول تحكم التنقل للتسجيل تحكم بغية أن يخطر على الملوثات العضوية الثابتة. لا يمكنك استخدام UINavigationControllerDelegate لأن هذا الواقع لا عمل عرض حقيقي).

وسويفت 4

override func viewWillDisappear(_ animated: Bool)
    {
        super.viewWillDisappear(animated)
        if self.isMovingFromParent
        {
            //View Controller Popped
        }
        else
        {
            //New view controller pushed
        }
    }

في سويفت:

 override func viewWillDisappear(animated: Bool) {
    if let navigationController = self.navigationController {
        if !contains(navigationController.viewControllers as! Array<UIViewController>, self) {
        }
    }

    super.viewWillDisappear(animated)

}

وأنا العثور على وثائق أبل على هذا من الصعب أن نفهم. هذا التمديد يساعد على معرفة الدول في كل التنقل.

extension UIViewController {
    public func printTransitionStates() {
        print("isBeingPresented=\(isBeingPresented)")
        print("isBeingDismissed=\(isBeingDismissed)")
        print("isMovingToParentViewController=\(isMovingToParentViewController)")
        print("isMovingFromParentViewController=\(isMovingFromParentViewController)")
    }
}

وهذه مسألة قديمة نوعا ما ولكن رأيت ذلك عن طريق الصدفة لذلك أريد للنشر أفضل الممارسات (AFAIK)

ويمكنك القيام به فقط

if([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
 // view controller popped
}

وهذا ينطبق على على iOS7 ، أو أي فكرة إذا كان ينطبق على أي منها الأخرى. من ما أعرفه، في viewDidDisappear وجهة نظر بالفعل تم برزت. وهو ما يعني عند الاستعلام self.navigationController.viewControllers ستحصل على nil. حتى مجرد معرفة ما اذا كان هذا هو لا شيء.

وTL، DR

 - (void)viewDidDisappear:(BOOL)animated
 {
    [super viewDidDisappear:animated];
    if (self.navigationController.viewControllers == nil) {
        // It has been popped!
        NSLog(@"Popped and Gone");
    }
 }

وsegues على أن يكون وسيلة فعالة جدا لمعالجة هذه المشكلة في دائرة الرقابة الداخلية 6+. إذا كنت قد أعطيت للسغ] معين معرف في واجهة باني يمكنك التحقق من ذلك في prepareForSegue.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"LoginSegue"]) {
       NSLog(@"Push");
       // Do something specific here, or set a BOOL indicating
       // a push has occurred that will be checked later
    }
}

وأفترض أنك يعني أن وجهة نظركم يتم نقلها أسفل كومة وحدة تحكم الملاحة من قبل دفع طريقة عرض جديدة عندما تقول دفعت إلى المكدس. أود أن أقترح باستخدام طريقة viewDidUnload لإضافة بيان NSLog أن أكتب شيئا إلى وحدة حتى تتمكن من معرفة ما يجري، قد ترغب في إضافة NSLog إلى viewWillDissappeer.

هنا هو فئة لإنجاز نفس الشيء sbrocket الجواب:

الرأس:

#import <UIKit/UIKit.h>

@interface UIViewController (isBeingPopped)

- (BOOL) isBeingPopped;

@end

المصدر:

#import "UIViewController+isBeingPopped.h"

@implementation UIViewController (isBeingPopped)

- (BOOL) isBeingPopped {
    NSArray *viewControllers = self.navigationController.viewControllers;
    if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
        return NO;
    } else if ([viewControllers indexOfObject:self] == NSNotFound) {
        return YES;
    }
    return NO;
}

@end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top