[ios] 뷰 컨트롤러가 모달로 표시되는지 또는 탐색 스택에 푸시되는지 확인하는 방법은 무엇입니까?

내 뷰 컨트롤러 코드에서 다음을 어떻게 구분할 수 있습니까?

  • 모달로 제시
  • 탐색 스택에 푸시 됨

둘 다 presentingViewController하고 isMovingToParentViewController있습니다 YES그래서 매우 도움이되지 않습니다, 두 경우 모두에서.

복잡한 것은 내 부모 뷰 컨트롤러가 때때로 모달이라는 것입니다.

그것은 내 문제는 내가 내를 포함한다는 것이다 밝혀 HtmlViewControllerA의 UINavigationController다음되게된다. 그래서 내 자신의 시도와 아래의 좋은 답변이 효과가 없었습니다.

HtmlViewController*     termsViewController = [[HtmlViewController alloc] initWithDictionary:dictionary];
UINavigationController* modalViewController;

modalViewController = [[UINavigationController alloc] initWithRootViewController:termsViewController];
modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:modalViewController
                   animated:YES
                 completion:nil];

결정하려고하는 대신 모달 일 때 뷰 컨트롤러에 알려주는 것이 좋습니다.



답변

테스트하지 않고 소금 한 알로 섭취하십시오.

- (BOOL)isModal {
     if([self presentingViewController])
         return YES;
     if([[[self navigationController] presentingViewController] presentedViewController] == [self navigationController])
         return YES;
     if([[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]])
         return YES;

    return NO;
 }


답변

에서 스위프트 :

클래스 유형별 모달인지 테스트 할 플래그를 추가합니다.

// MARK: - UIViewController implementation

extension UIViewController {

    var isModal: Bool {

        let presentingIsModal = presentingViewController != nil
        let presentingIsNavigation = navigationController?.presentingViewController?.presentedViewController == navigationController
        let presentingIsTabBar = tabBarController?.presentingViewController is UITabBarController

        return presentingIsModal || presentingIsNavigation || presentingIsTabBar
    }
}


답변

한 가지 방법을 간과했습니다 : isBeingPresented.

isBeingPresented 뷰 컨트롤러가 표시되면 true이고 푸시되면 false입니다.

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

    if ([self isBeingPresented]) {
        // being presented
    } else if ([self isMovingToParentViewController]) {
        // being pushed
    } else {
        // simply showing again because another VC was dismissed
    }
}


답변

Swift 5
다음은 푸시 된 경우 isModal()반환 이 제시된 스택 에 있을 때 이전 답변에서 언급 된 문제를 해결하는 솔루션입니다 .trueUIViewControllerUINavigationController

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if navigationController?.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}

지금까지 나를 위해 작동합니다. 일부 최적화가 있으면 공유하십시오.


답변

self.navigationController! = nil은 탐색 스택에 있음을 의미합니다.

탐색 컨트롤러가 모달로 표시되는 동안 현재 뷰 컨트롤러가 푸시되는 경우를 처리하기 위해 현재 뷰 컨트롤러가 탐색 스택의 루트 컨트롤러인지 확인하는 몇 줄의 코드를 추가했습니다.

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if let navigationController = navigationController, navigationController.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if let tabBarController = tabBarController, tabBarController.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}


답변

스위프트 4

var isModal: Bool {
    return presentingViewController != nil ||
           navigationController?.presentingViewController?.presentedViewController === navigationController ||
           tabBarController?.presentingViewController is UITabBarController
}


답변

Swift 5. 깨끗하고 간단합니다.

if navigationController.presentingViewController != nil {
    // Navigation controller is being presented modally
}