iphone modalpresentationstyle - ViewController가 Modal로 표시되는지 여부를 판별 할 수 있습니까?




swift custom (13)

모달 뷰 컨트롤러로 제공되는 ViewController 클래스 내부를 검사 할 수 있습니까?


Answers

나를 위해 일한 것은 다음과 같습니다 :

// this is the trick: set parent view controller as application's window root view controller
UIApplication.sharedApplication.delegate.window.rootViewController = viewController;

// assert no modal view is presented
XCTAssertNil(viewController.presentedViewController);

// simulate button tap which shows modal view controller
[viewController.deleteButton sendActionsForControlEvents:UIControlEventTouchUpInside];

// assert that modal view controller is presented
XCTAssertEqualObjects(viewController.presentedViewController.class, MyModalViewController.class);

내가 테스트 한 내용은 iOS7 및 iOS8에서 작동합니다. 그러나 iOS6에서 시도하지 않았습니다.


self.navigationController가 모달로 표시되었지만 self가 self.navigationController.viewControllers [0]과 같지 않으면 Petronella의 대답 이 작동하지 않습니다.이 경우 self가 푸시됩니다.

다음은 문제를 해결할 수있는 방법입니다.

return self.presentingViewController.presentedViewController == self
            || (self.navigationController != nil && self.navigationController.presentingViewController.presentedViewController == self.navigationController && self == self.navigationController.viewControllers[0])
            || [self.tabBarController.presentingViewController isKindOfClass:[UITabBarController class]];

스위프트 :

return self.presentingViewController?.presentedViewController == self
        || (self.navigationController != nil && self.navigationController?.presentingViewController?.presentedViewController == self.navigationController && self.navigationController?.viewControllers[0] == self)
        || self.tabBarController?.presentingViewController is UITabBarController

modalViewController 는 iOS 6에서 사용되지 않으므로 iOS 5 이상에서 작동하며 경고없이 컴파일되는 버전입니다.

목표 -C :

- (BOOL)isModal {
    return self.presentingViewController.presentedViewController == self
      || (self.navigationController != nil && self.navigationController.presentingViewController.presentedViewController == self.navigationController)
      || [self.tabBarController.presentingViewController isKindOfClass:[UITabBarController class]];
}

빠른:

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

모자 팁으로 펠리페의 대답.


iOS5 +에서는 UIViewController 클래스 참조 에서 볼 수 있듯이 "presentingViewController"속성에서 가져올 수 있습니다.

presentingViewController이 뷰 컨트롤러를 제공 한 뷰 컨트롤러입니다. (읽기 전용)

@property (비 원자, 읽기 전용) UIViewController * presentingViewController
토론

이 메시지를받은보기 컨트롤러가 다른보기 컨트롤러에 의해 표시되는 경우이 속성은 현재 표시중인보기 컨트롤러를 보유합니다. 뷰 컨트롤러가 표시되지 않지만 해당 조상 중 하나가 표시되면이 속성은 가장 가까운 조상을 표시하는 뷰 컨트롤러를 유지합니다. 뷰 컨트롤러와 그 조상 중 하나도 표시되지 않으면이 속성은 nil을 유지합니다.

유효성
iOS 5.0 이상에서 사용할 수 있습니다.
신고 된
UIViewController.h


이것은 효과가있다.

if(self.parentViewController.modalViewController == self)…

확인하는 가장 좋은 방법

 if (self.navigationController.presentingViewController) {
         NSLog(@"Model Present");
    }

존재하지 않으면 UIViewController 하위 클래스에서 this ( presentedAsModal )에 대한 속성을 정의하고 ViewController를 모달보기로 표시하기 전에 YES 설정할 수 있습니다.

childVC.presentedAsModal = YES;
[parentVC presentModalViewController:childVC animated:YES];

viewWillAppear 재정의에서이 값을 확인할 수 있습니다.

나는 전망이 제시되는 방법을 진술하는 공식적인 재산이 없다고 믿는다. 그러나 아무것도 당신 자신을 만들지 못하게한다.


스위프트 :

func isUIViewControllerPresentedAsModal() -> Bool {
    if((self.presentingViewController) != nil) {
        return true
    }

    if(self.presentingViewController?.presentedViewController == self) {
        return true
    }

    if(self.navigationController?.presentingViewController?.presentedViewController == self.navigationController) {
        return true
    }

    if((self.tabBarController?.presentingViewController?.isKindOfClass(UITabBarController)) != nil) {
        return true
    }

    return false
}

다음은 @ GabrielePetronella의 수정 된 버전입니다. isModalisModal 계층 구조를 먼저 살펴 보도록 포함 된 뷰 컨트롤러와 함께 작동합니다. 또한 코드를 여러 줄로 가져 와서 코드가 무엇을하는지 분명하게 알 수 있습니다.

var isModal: Bool {
    // If we are a child view controller, we need to check our parent's presentation
    // rather than our own.  So walk up the chain until we don't see any parentViewControllers
    var potentiallyPresentedViewController : UIViewController = self
    while (potentiallyPresentedViewController.parentViewController != nil) {
        potentiallyPresentedViewController = potentiallyPresentedViewController.parentViewController!
    }

    if self.presentingViewController?.presentedViewController == potentiallyPresentedViewController {
        return true
    }

    if let navigationController = potentiallyPresentedViewController.navigationController {
        if navigationController.presentingViewController?.presentedViewController == navigationController {
            return true
        }
    }

    return potentiallyPresentedViewController.tabBarController?.presentingViewController is UITabBarController
}

내 프로젝트에서 모달보기 컨트롤러에 의해 모달로 (새 항목을 추가 할 때) 또는 푸시 (기존 항목을 편집 할 때)로 표시 할 수있는보기 컨트롤러 (Detail)가 있습니다. 사용자가 [완료]를 두 드리면 상세보기 컨트롤러는 마스터보기 컨트롤러의 메소드를 호출하여 닫힐 준비가되었음을 알립니다. 스승님은 세부 사항이 어떻게 닫히는 지 알기 위해 그것이 어떻게 나타나는지를 결정해야한다. 이것이 내가하는 일입니다.

UIViewController *vc = self.navigationController.viewControllers.lastObject;
if (vc == self) {
    [self dismissViewControllerAnimated:YES completion:NULL];
} else {
    [self.navigationController popViewControllerAnimated:YES];
}

iOS 6 이상을 찾고 있다면이 답변은 사용되지 않으며 Gabriele Petronella의 대답을 확인해야합니다.

UIKit 고유의 속성 또는 메서드로이를 수행 할 수있는 깔끔한 방법은 없습니다. 컨트롤러의 여러 측면을 점검하여 모달로 표시되는지 확인하십시오.

그래서, 현재 (코드 벨로우즈에서 self 로 표현됨) 컨트롤러가 모달 방식으로 표현되는지 아닌지를 확인하기 위해 UIViewController 범주에서 기능을 선택하거나 (다른 UIKit 컨트롤러를 사용할 필요가없는 프로젝트 일 경우) , 예를 들어 UITableViewController 같은) 다른 컨트롤러가 상속하는 기본 컨트롤러

-(BOOL)isModal {

     BOOL isModal = ((self.parentViewController && self.parentViewController.modalViewController == self) || 
            //or if I have a navigation controller, check if its parent modal view controller is self navigation controller
            ( self.navigationController && self.navigationController.parentViewController && self.navigationController.parentViewController.modalViewController == self.navigationController) || 
            //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
            [[[self tabBarController] parentViewController] isKindOfClass:[UITabBarController class]]);

    //iOS 5+
    if (!isModal && [self respondsToSelector:@selector(presentingViewController)]) {

        isModal = ((self.presentingViewController && self.presentingViewController.modalViewController == self) || 
             //or if I have a navigation controller, check if its parent modal view controller is self navigation controller
             (self.navigationController && self.navigationController.presentingViewController && self.navigationController.presentingViewController.modalViewController == self.navigationController) || 
             //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
             [[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]]);

    }

    return isModal;        

}

편집 : UITabBarController 사용중인 경우 마지막 검사를 추가하고 모달로 다른 UITabBarController 제시.

2 편집 : UIViewController 더 이상 parentViewController 대한 응답하지 않지만 대신 presentingViewController iOS 5 + 확인을 추가했습니다.

편집 3 : 나는 그것을 위해 요지를 만들었습니다. https://gist.github.com/3174081


프로젝트의 경우와 같이 전체 화면 모달보기와 모달이 아닌보기를 구분할 필요가없는 경우 (양식 시트 및 페이지 시트에서만 발생하는 문제를 처리하고 있음) modalPresentationStyle UIViewController 속성 :

switch (self.modalPresentationStyle) {
    case 0: NSLog(@"full screen, or not modal"); break;
    case 1: NSLog(@"page sheet"); break;
    case 2: NSLog(@"form sheet"); break;
}

나는 같은 문제를 가지고 있었다.

$('#myModal').on('hidden.bs.modal', function () {
// do something… })

이것을 페이지 맨 아래에 놓아야하며 맨 위에 놓으면 이벤트가 실행되지 않습니다.







iphone ios view controller modal-dialog