[ios] viewWillDisappear : 뷰 컨트롤러가 팝업되는지 또는 서브 뷰 컨트롤러를 표시 중인지 확인

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

물론 viewinillDisappear가 호출 될 때까지 UINavigationController의 뷰 컨트롤러 스택 (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 문서에서 :

“이 4 가지 방법은 뷰 컨트롤러의 모양 콜백에서 하위 뷰 컨트롤러로 표시, 해제 또는 추가 또는 제거되는지 여부를 결정하는 데 사용될 수 있습니다. 예를 들어, 뷰 컨트롤러는 뷰 컨트롤러가 해제되었거나 사라져서 사라 졌는지 확인할 수 있습니다. viewWillDisappear : 메소드에서 식 ([self isBeingDismissed] || [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]) {
    }
}

스위프트 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)

}


답변

이것에 관한 Apple의 문서는 이해하기 어렵다는 것을 알았습니다. 이 확장은 각 탐색에서 상태를 보는 데 도움이됩니다.

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