programing

ViewWillDisposure:보기 컨트롤러가 팝업되는지 또는 하위 보기 컨트롤러를 표시하는지 확인합니다.

abcjava 2023. 6. 10. 07:55
반응형

ViewWillDisposure:보기 컨트롤러가 팝업되는지 또는 하위 보기 컨트롤러를 표시하는지 확인합니다.

저는 이 문제에 대한 좋은 해결책을 찾기 위해 고군분투하고 있습니다.뷰 컨트롤러의-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");
  }
}

물론 이는 viewWillDisappear가 호출될 때까지 UINavigationController의 ViewController 스택(viewControllers 속성을 통해 노출됨)이 업데이트되었기 때문에 가능합니다.

가장 쉬운 방법은 다음과 같습니다.

 - (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 isMovingFromParent
    {
        print("View controller was popped")
    }
    else
    {
        print("New view controller was pushed")
    }
    super.viewWillDisappear(animated)
}

UIViewController.h에 있는 Apple 설명서에서:

"이 네 가지 방법은 뷰 컨트롤러의 모양 콜백에 사용하여 뷰 컨트롤러가 하위 뷰 컨트롤러로 표시, 해제 또는 추가 또는 제거되는지 확인할 수 있습니다.예를 들어, 뷰 컨트롤러는 자신의 뷰에서 자신에게 질문하여 자신이 제거되었거나 팝업되었기 때문에 사라지는지 확인할 수 있습니다. WillDispare: method는 식([self is BeingDismissed] || [self 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]) {
    }
}

Swift 3 버전:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    if self.isBeingDismissed || self.isMovingFromParentViewController { 
    }
}

스위프트 4

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

만약 당신이 당신의 견해가 튀어나오고 있는지 알고 싶다면, 저는 방금 그것을 발견했습니다.self.navigationController이라nilviewDidDisappear컨트롤러 스택에서 제거되는 경우.이것이 간단한 대체 테스트입니다.

(이것은 제가 다른 모든 종류의 왜곡을 시도해 본 후에 발견합니다.팝업에 알림을 받을 뷰 컨트롤러를 등록하는 내비게이션 컨트롤러 프로토콜이 없다는 것이 놀랍습니다.사용할 수 없습니다.UINavigationControllerDelegate실제 디스플레이 작업을 수행하기 때문입니다.)

Swift에서:

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

    super.viewWillDisappear(animated)

}

감사합니다. @Bryan Henry, 여전히 Swift 5에서 일합니다.

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if let controllers = navigationController?.children{
            if controllers.count > 1, controllers[controllers.count - 2] == self{
                // View is disappearing because a new view controller was pushed onto the stack
                print("New view controller was pushed")
            }
            else if controllers.firstIndex(of: self) == nil{
                // View is disappearing because it was popped from the stack
                print("View controller was popped")
            }
        }

    }

저는 이것에 대한 애플의 문서가 이해하기 어렵다고 생각합니다.이 확장 기능은 각 탐색의 상태를 볼 수 있도록 도와줍니다.

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

이 질문은 꽤 오래된 질문이지만 실수로 봐서 베스트 프랙티스를 올리고 싶습니다 (afak)

당신은 그냥 할 수 있습니다

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

이것은 iOS7에 적용됩니다. 다른 OS에도 적용되는지는 알 수 없습니다.제가 알기로는viewDidDisappear보기가 이미 팝업되었습니다.그 말은 당신이 질문할 때self.navigationController.viewControllers당신은 a를 받을 것입니다.nil그래서 그것이 0인지만 확인하세요.

TL;DR

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

Segues는 iOS 6+에서 이 문제를 처리하는 매우 효과적인 방법이 될 수 있습니다. Interface Builder에서 할 수 .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
    }
}

새 뷰를 스택에 밀어넣으면 탐색 컨트롤러의 스택 아래로 보기가 이동된다는 의미인 것 같습니다.는 사할것제안다니합을용을 하는 을 추천합니다.viewDidUnloadNSLog무슨 일이 일어나고 있는지 볼 수 있도록 콘솔에 무언가를 쓰기 위한 문장, 당신은 아마도 추가하고 싶을 것입니다.NSLogviewWillDissappeer.

다음은 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

언급URL : https://stackoverflow.com/questions/1816614/viewwilldisappear-determine-whether-view-controller-is-being-popped-or-is-showi

반응형