보기가 창 계층 구조에없는 UIViewController에 UIViewController를 표시하려고 시도합니다.


599

Xcode 4.5를 사용하기 시작했고 콘솔 에서이 오류가 발생했습니다.

경고 :보기가 창 계층 구조에없는 <ViewController : 0x1ec3e000>에 <finishViewController : 0x1e56e0a0>을 (를) 표시하십시오!

뷰가 계속 표시되고 앱의 모든 것이 제대로 작동합니다. iOS 6의 새로운 기능입니까?

이것은 뷰 사이를 변경하는 데 사용하는 코드입니다.

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished = 
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];

3
presentViewController:animated:completion탐색 컨트롤러 를 호출하려고하는 것을 제외하고는 똑같은 문제가 있습니다. 앱 델리게이트에서이 작업을 수행하고 있습니까?
tarnfeld

아니요 한보 기 컨트롤러에서 다른보기 컨트롤러로하고 있습니다. 해결책을 찾았습니까?
Kyle Goslan

Xcode 4.5를 사용하기 전에 항상 작동하는 코드 부분에서 동일한 문제가 발생합니다. UINavigationController를 제시하지만 다시는 항상 이전에 작동했습니다.
Emanuele Fumagalli

나는 해결되지 않은 같은 문제가 있습니다. 앱 대리자 및 UITabBarController에서 "presentViewController"를 호출하는 rootviewcontroller에서 수행합니다.
darksider

3
또한 makeKeyAndVisible을 호출하기 전에이 메소드를 호출하는 경우에는 그 다음으로 이동하십시오.
mike_haney

답변:


1296

이 메소드를 어디에서 호출합니까? viewDidLoad메서드 내에서 모달 뷰 컨트롤러를 제시하려고하는데 문제가있었습니다 . 나를위한 해결책은이 호출을 viewDidAppear:메소드 로 옮기는 것이 었습니다 .

내 가정은 뷰 컨트롤러의 뷰가 있다는 것입니다 하지 합니다 (이로드 된 시점에서 윈도우의 뷰 계층에 viewDidLoad메시지가 전송), 그러나 그것은 이다 가 발표 된 후 윈도우 계층합니다 (경우에 viewDidAppear:메시지가 전송됩니다) .


주의

당신이를 호출 할 할 경우 presentViewController:animated:completion:viewDidAppear:모달 뷰 컨트롤러는 항상 제공되고, 이에 당신이 문제로 실행할 수를 때마다 뷰 컨트롤러의 뷰가 나타납니다 (어떤 의미!)과 모달 뷰 컨트롤러는 멀리 가지 않을 것되게되고, 그래서 .. .

어쩌면 이것이 모달 뷰 컨트롤러를 표시하기에 가장 좋은 장소가 아니거나, 또는 추가 뷰 상태를 유지해야하는 경우도 있는데,이를 통해 프리젠 테이션 뷰 컨트롤러가 모달 뷰 컨트롤러를 즉시 표시해야하는지 여부를 결정할 수 있습니다.


6
@ 제임스는보기가 분명히 때까지 계층 구조가 아닌, 올바른 viewWillAppear가 해결되었습니다 및 viewDidAppear가 호출 된 후. 이것이 내 질문이라면 나는이 대답을 받아 들일 것이다;)
Matt Mc

6
@ 제임스 감사합니다. ViewDidAppear를 사용하면 나에게도 문제가 해결되었습니다. 맞는 말이다.
Ali

44
나는 이것을 두 번 공표 할 수 있으면 좋겠다. 방금이 문제가 있었고 마지막으로 보았을 때 이미 upvoted 한 것을 발견하기 위해 스레드에 왔습니다.
Schrockwell

7
viewDidAppear에서 VC를 변경하면 Animation으로 segue가 실행됩니다. 배경을 플래시 / 표시합니다.
Vincent

2
예, 트릭은 올바른 viewWillAppear : (BOOL) 애니메이션입니다. [super viewDidAppear : animated]와 같이 메소드에서 super를 호출해야하는 또 하나의 중요한 사항입니다. 이것이 없으면 작동하지 않습니다.
BootMaker

66

또 다른 잠재적 인 원인 :

실수로 동일한 뷰 컨트롤러를 두 번 제시 할 때이 문제가 발생했습니다. (한 번 performSegueWithIdentifer:sender:버튼을 눌렀을 때 호출되었고, 세그가 버튼에 직접 연결된 상태에서 두 번째로 호출되었습니다).

효과적으로, 두 개의 segue가 동시에 발사되었고, 나는 오류가 발생했습니다. Attempt to present X on Y whose view is not in the window hierarchy!


4
나는 같은 오류가 있었고 여기서 당신의 대답은 무슨 일이 일어나고 있는지 알아내는 데 도움이되었습니다. 실제로이 오류는 당신 때문에
고쳤

1
이전 segue를 삭제하고 VC를 VC에 연결했습니다. 버튼을 스토리 보드에 VC에 연결하는 방법이 있습니까?
MCB

나는 같은 오류가 있었고, 당신의 대답은 내 문제를 해결했습니다. 친절합니다.
iamburak

1
lol, 우연히 나는 또한 두 개의 vc를 만들었습니다.
Borzh

1
제 경우 present(viewController, animated: true, completion: nil)에는 루프 내부 를 호출 했습니다.
Samo

38

viewWillLayoutSubviewsviewDidLayoutSubviews(아이폰 OS가 5.0)이 목적을 위해 이용 될 수있다. viewDidAppear보다 먼저 호출됩니다.


3
여전히 다른 경우에도 사용되므로 뷰의 "평생"에서 여러 번 호출 될 수 있습니다.
Jonny

또한 이름에서 알 수 있듯이 방법이 아닙니다. viewDidAppear가 정확합니다. 뷰 라이프 사이클을 읽는 것이 좋습니다.
tooluser

이것이 가장 좋은 해결책입니다. 필자의 경우 viewDidAppear에 표시하면 모달이로드되기 전에 뷰 컨트롤러가 두 번째로 표시되어 허용되지 않습니다.
TMilligan

이 답변은 경고를 표시하려고 할 때 가장 효과적이었습니다. viewDidLoad 및 viewWillAppear에 넣을 때 경고가 표시되지 않습니다.
uplearnedu.com

26

하위 뷰를 메인 뷰에 표시하려면 다음 코드를 사용하십시오

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];

메인 뷰에서 하위 뷰를 해제하려면 다음 코드를 사용하십시오

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];

나를 위해
Aziz Javed

17

에서을 (를) 제시하려고 할 때도이 문제가 발생 UIViewController했습니다 viewDidLoad. James Bedford의 답변은 효과가 있었지만 내 앱은 1 ~ 2 초 동안 배경을 먼저 보여주었습니다.

약간의 연구 끝에,를 사용하여 이것을 해결할 수있는 방법을 찾았습니다 addChildViewController.

- (void)viewDidLoad
{
    ...
    [self.view addSubview: navigationViewController.view];
    [self addChildViewController: navigationViewController];
    ...
}

9
[navigationViewController didMoveToParentViewController : self]가 없습니다.
foFox

2
foFox의 제안과 함께 코드를 시도했지만 부모에서 코드를 제거하면 사라지지 않습니다. Lololol. 여전히 고쳐지지 않았습니다.
Logicsaurus Rex

스위프트 3.1에서 작동
Kang Byul

presentviewcontroller 전에 사용되는 두 줄 위의 @sunkehappy, 왜 충돌 했습니까?
Iyyappan Ravi

14

아마 나처럼 너는 틀린 뿌리를 가지고있어 viewController

나는를 표시 할 ViewControllerA의 non-UIViewController컨텍스트

그래서 나는 그런 코드를 사용할 수 없습니다 :

[self presentViewController:]

그래서 UIViewController를 얻습니다.

[[[[UIApplication sharedApplication] delegate] window] rootViewController]

어떤 이유로 (논리적 버그) rootViewController는 예상 이외의 것입니다 (정상 UIViewController). 그럼, 버그를 수정 교체 rootViewController로모그래퍼 UINavigationController하고 문제가 사라입니다.


8

TL; DR 1 개의 rootViewController와 가장 최근에 표시된 것만 가질 수 있습니다. 따라서 뷰 컨트롤러가 이미 닫히지 않은 뷰 컨트롤러를 제공 할 때 다른 뷰 컨트롤러를 제시하려고 시도하지 마십시오.

내 자신의 테스트 중 일부를 수행 한 후 결론에 도달했습니다.

모든 것을 제시하려는 rootViewController가 있으면이 문제가 발생할 수 있습니다.

여기 내 rootController 코드가 있습니다 (open은 루트에서 viewcontroller를 표시하는 바로 가기입니다).

func open(controller:UIViewController)
{
    if (Context.ROOTWINDOW.rootViewController == nil)
    {
        Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
        Context.ROOTWINDOW.makeKeyAndVisible()
    }

    ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
}

(시간 경과에 관계없이) 연속으로 두 번 open을 호출하면 첫 번째 열림에서는 잘 작동하지만 두 번째 열림에서는 잘 작동하지 않습니다. 두 번째 열린 시도는 위의 오류를 발생시킵니다.

그러나 가장 최근에 표시된보기를 닫은 다음 open open을 사용하면 (다른 viewcontroller에서) open을 다시 호출하면 정상적으로 작동합니다.

func close(controller:UIViewController)
{
    ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
}

내가 결론을 내린 것은 MOST-RECENT-CALL만의 rootViewController가 뷰 계층에 있다는 것입니다 (뷰를 닫지 않았거나 뷰를 제거하지 않더라도). 모든 로더 호출 (viewDidLoad, viewDidAppear 및 지연 된 디스패치 호출 수행)을 사용하여 시도했지만 작동시킬 수있는 유일한 방법은 최상위 뷰 컨트롤러에서만 present를 호출하는 것입니다.


이것은 많은 답변이 귀하의 투표를 한 훨씬 일반적인 문제처럼 보입니다. 불행히도, 이것은 매우 도움이되었습니다
rayepps

예, 모두 훌륭하지만 해결책은 무엇입니까 ... 배경 작업자 스레드가 서버에 가서 스토리 보드를 오른쪽과 가운데에 표시하고 전체 방법론이 가짜입니다 .. 끔찍합니다. 내가 배경 스레드가 int하고 싶기 때문에 농담 : wait wait decide push screen to front그것은 불가능하다 IOS ????
Mr Heelis

5

내 문제는 창을 호출하기 전에 UIApplicationDelegatedidFinishLaunchingWithOptions방법으로 segue를 수행하는 것이 었습니다 makeKeyAndVisible().


어떻게? 정교하게 할 수 있습니까? 나는 같은 문제에 직면하고있다. UIViewController에 self.window .rootViewController = initialViewControlleripad self.window .makeKeyAndVisible ()로? : UIViewController에 = mainStoryboardIpad.instantiateViewController ( "SplashController"withIdentifier :)이 내 코드가 initialViewControlleripad을 할 수있다
shahtaj 칼리드

4

내 상황에서 나는 클래스 재정의에 내 것을 넣을 수 없었다. 그래서, 여기 내가 가진 것이 있습니다 :

let viewController = self // I had viewController passed in as a function,
                          // but otherwise you can do this


// Present the view controller
let currentViewController = UIApplication.shared.keyWindow?.rootViewController
currentViewController?.dismiss(animated: true, completion: nil)

if viewController.presentedViewController == nil {
    currentViewController?.present(alert, animated: true, completion: nil)
} else {
    viewController.present(alert, animated: true, completion: nil)
}

3

나는 같은 문제가 있었다. 내비게이션 컨트롤러를 내장하고이를 통해 컨트롤러를 제시해야했습니다. 다음은 샘플 코드입니다.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIImagePickerController *cameraView = [[UIImagePickerController alloc]init];
    [cameraView setSourceType:UIImagePickerControllerSourceTypeCamera];
    [cameraView setShowsCameraControls:NO];

    UIView *cameraOverlay = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 768, 1024)];
    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"someImage"]];
    [imageView setFrame:CGRectMake(0, 0, 768, 1024)];
    [cameraOverlay addSubview:imageView];

    [cameraView setCameraOverlayView:imageView];

    [self.navigationController presentViewController:cameraView animated:NO completion:nil];
//    [self presentViewController:cameraView animated:NO completion:nil]; //this will cause view is not in the window hierarchy error

}


3

나는 같은 문제가 있었다. 문제는 메인 스레드에 알림을 넣 자마자 경고 메시지가 사라지면 performSegueWithIdentifier가 알림에 의해 트리거되었다는 것입니다.


3

잘 작동하고 있습니다. 링크

UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
[top presentViewController:secondView animated:YES completion: nil];

3

누군가에게 도움이되는 경우 내 문제는 매우 어리 석었습니다. 물론 내 잘못이야. 알림이 모달을 호출하는 메소드를 트리거했습니다. 그러나 알림을 올바르게 제거하지 않았으므로 어느 시점에서 두 개 이상의 알림이 있으므로 모달이 여러 번 호출됩니다. 물론 모달을 한 번 호출 한 후이를 호출하는 뷰 컨트롤러는 더 이상 뷰 계층 구조에 있지 않으므로이 문제가 발생합니다. 내 상황은 당신이 예상 한 것처럼 다른 많은 문제를 야기했습니다.

요약하자면, 무엇을 하든지 모달이 두 번 이상 호출되지 않아야 합니다.


3

나는 viewController거의 모든 곳에서 일부를 표시하려는 것을 고려할 때 마침내 나에게 작동하는 코드 (Swift)로 끝났습니다 . 이 코드는 사용 가능한 rootViewController가 없으면 분명히 중단됩니다. 또한 일반적으로 필요한 UI 스레드로의 전환을 포함하지 않습니다

dispatch_sync(dispatch_get_main_queue(), {
    guard !NSBundle.mainBundle().bundlePath.hasSuffix(".appex") else {
       return; // skip operation when embedded to App Extension
    }

    if let delegate = UIApplication.sharedApplication().delegate {
        delegate.window!!.rootViewController?.presentViewController(viewController, animated: true, completion: { () -> Void in
            // optional completion code
        })
    }
}

BTW는이 메소드를 어디에서 호출 해야하는지 이해합니다. 그렇지 않으면 UI가없는 SDK 라이브러리이므로 특정 (비공개) 경우 앱에 고유 한 UI를 표시합니다.
igraczech

확장명이있는 앱에 SDK를 삽입하기로 결정하면 충돌이 발생합니다. UIViewController를 전달하여 sdk init 메소드를 남용하십시오.
Anton Tropashko

당신은 진실한 Anton입니다. 이 코드는 Extensions가없고 SDK를 아직 사용하지 않았을 때 작성되었습니다. 이 대소 문자를 건너 뛰기 위해 가드 절을 추가했습니다.
igraczech

3

이런 종류의 경고는 귀하 가 현재 다른 것을 제시하는 동안 새로운 발표 View Controller를 시도하고 있음을 의미 할 수 있습니다 . 문제를 해결하려면 처음에 현재 제시된 내용을 닫고 완료시 새로운 내용을 제시해야합니다. 경고의 또 다른 원인은 이외의 스레드에 표시하려고 할 수 있습니다 .Navigation ControllerNavigation ControllerView ControllerView ControllerView Controllermain


3

Swift 4.2 에서도 비슷한 문제가 있었지만 뷰 사이클에서 뷰가 표시되지 않았습니다. 나는 동시에 여러 개의 발표를 발표했다. 그래서 dispatchAsyncAfter를 사용했습니다.

func updateView() {

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in

// for programmatically presenting view controller 
// present(viewController, animated: true, completion: nil)

//For Story board segue. you will also have to setup prepare segue for this to work. 
 self?.performSegue(withIdentifier: "Identifier", sender: nil)
  }
}

2

완성 블록 start()내에서 함수 를 이동하여 수정했습니다 dismiss.

self.tabBarController.dismiss(animated: false) {
  self.start()
}

시작에는 self.present()UINavigationController에 대한 호출 하나와에 대한 호출 하나 가 포함 UIImagePickerController됩니다.

그것은 나를 위해 그것을 고쳤다.


1

컨테이너에 포함 된 뷰 컨트롤러에서 segue를 수행 할 때이 경고가 표시 될 수도 있습니다. 올바른 해결책은 컨테이너의 뷰 컨트롤러가 아닌 컨테이너의 상위에서 segue를 사용하는 것입니다.


1

아래 줄을 작성해야합니다.

self.searchController.definesPresentationContext = true

대신에

self.definesPresentationContext = true

UIViewController에서


1

스위프트 3과 함께 ...

나에게 일어난 이것의 또 다른 가능한 원인은 tableViewCell에서 스토리 보드의 다른 ViewController로 segue가 있었기 때문입니다. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}셀을 클릭했을 때도 사용했습니다 .

ViewController에서 ViewController로 segue를 만들어이 문제를 해결했습니다.


1

나는이 문제가 있었고 근본 원인은 버튼 클릭 핸들러 (TouchUpInside)를 여러 번 구독하고있었습니다.

ViewWillAppear에 가입하고 있었는데 다른 컨트롤러로 이동하기 위해 탐색을 추가 한 후 다시 풀기 한 이후 여러 번 호출되었습니다.


1

스토리 보드segue가 고장났다는 것이 나에게 일어났다 . segue를 삭제하고 다시 동일한 segue를 작성하면 문제가 해결되었습니다.


1

주 창에서는 항상 경고 표시와 호환되지 않는 전환이있을 수 있습니다. 응용 프로그램 수명주기에서 언제든지 경고를 표시하려면 작업을 수행 할 별도의 창이 있어야합니다.

/// independant window for alerts
@interface AlertWindow: UIWindow

+ (void)presentAlertWithTitle:(NSString *)title message:(NSString *)message;

@end

@implementation AlertWindow

+ (AlertWindow *)sharedInstance
{
    static AlertWindow *sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[AlertWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    });
    return sharedInstance;
}

+ (void)presentAlertWithTitle:(NSString *)title message:(NSString *)message
{
    // Using a separate window to solve "Warning: Attempt to present <UIAlertController> on <UIViewController> whose view is not in the window hierarchy!"
    UIWindow *shared = AlertWindow.sharedInstance;
    shared.userInteractionEnabled = YES;
    UIViewController *root = shared.rootViewController;
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    alert.modalInPopover = true;
    [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        shared.userInteractionEnabled = NO;
        [root dismissViewControllerAnimated:YES completion:nil];
    }]];
    [root presentViewController:alert animated:YES completion:nil];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    self.userInteractionEnabled = NO;
    self.windowLevel = CGFLOAT_MAX;
    self.backgroundColor = UIColor.clearColor;
    self.hidden = NO;
    self.rootViewController = UIViewController.new;

    [NSNotificationCenter.defaultCenter addObserver:self
                                           selector:@selector(bringWindowToTop:)
                                               name:UIWindowDidBecomeVisibleNotification
                                             object:nil];

    return self;
}

/// Bring AlertWindow to top when another window is being shown.
- (void)bringWindowToTop:(NSNotification *)notification {
    if (![notification.object isKindOfClass:[AlertWindow class]]) {
        self.hidden = YES;
        self.hidden = NO;
    }
}

@end

설계 상 항상 성공할 기본 사용법 :

[AlertWindow presentAlertWithTitle:@"My title" message:@"My message"];

1

슬프게도, 수용 된 해결책이 내 경우에는 효과가 없었습니다. 다른 View Controller에서 긴장을 풀 자마자 새 View Controller로 이동하려고했습니다.

어떤 unwind segue가 호출되었는지 나타내는 플래그를 사용하여 해결책을 찾았습니다.

@IBAction func unwindFromAuthenticationWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToMainTabBar = true
}

@IBAction func unwindFromForgetPasswordWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToLogin = true
}

그런 다음 원하는 VC를 제시하십시오. present(_ viewControllerToPresent: UIViewController)

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if self.shouldSegueToMainTabBar {
        let mainTabBarController = storyboard.instantiateViewController(withIdentifier: "mainTabBarVC") as! MainTabBarController
        self.present(mainTabBarController, animated: true)
        self.shouldSegueToMainTabBar = false
    }
    if self.shouldSegueToLogin {
        let loginController = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
        self.present(loginController, animated: true)
        self.shouldSegueToLogin = false
    }
}

기본적으로 위의 코드를 사용하면 로그인 / 가입 VC에서 풀기를 해제하고 대시 보드로 이동하거나 암호 VC를 잊어 버림에서 풀기 작업을 포착하여 로그인 페이지로 이동할 수 있습니다.


1

rootViewController를 순환하는 동안 발견되는 상수로 최상위 viewcontroller를 저장 하여이 오류를 수정했습니다.

if var topController = UIApplication.shared.keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }
    topController.present(controller, animated: false, completion: nil)
    // topController should now be your topmost view controller
}

1

Xcode를 업데이트 한 후이 버그가 발견되었습니다 .Swift 5를 믿습니다 . 뷰 컨트롤러를 풀고 나서 프로그래밍 방식으로 segue를 직접 시작했을 때 문제가 발생했습니다.

솔루션은 관련 버그를 수정하는 동안 도착했으며, 이제 사용자가 페이지를 아래로 스 와이프하여 segue를 풀 수있었습니다. 이것은 내 프로그램의 논리를 어겼습니다.

모든 뷰 컨트롤러의 프레젠테이션 모드를 자동 에서 전체 화면 으로 변경하여 수정했습니다 .

인터페이스 빌더의 속성 패널에서이를 수행 할 수 있습니다. 또는 프로그래밍 방식으로 수행하는 방법에 대해서는 이 답변 을 참조하십시오 .


0

방금이 문제가 있었지만 타이밍과 관련이 없었습니다. 장면을 처리하기 위해 싱글 톤을 사용하고 있었고 발표자로 설정했습니다. 다시 말해서 "자기"는 아무것도 연결되지 않았습니다. 방금 내부의 "장면"을 새로운 발표자와 짜잔으로 만들었습니다. (Voila는 의미를 익힌 후에는 손길을 잃습니다.)

따라서 "매직 적으로 올바른 방법을 찾는 것"이 ​​아니라 코드의 위치와 수행중인 작업을 이해하는 것입니다. 나는 애플이 감정을 가지고도 평범한 영어 경고 메시지를 준 것이 기쁘다. 그렇게 한 애플 개발자에게 칭찬을 !!


0

어떤 이유로 다른 솔루션이 좋지 않은 경우에도 다음 workaround과 같이 지연이 0 인이 오래된 프레젠테이션을 계속 사용할 수 있습니다 .

dispatch_after(0, dispatch_get_main_queue(), ^{
    finishViewController *finished = [self.storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
    [self presentViewController:finished animated:NO completion:NULL];    
});

귀하의 VC가 타임 디스패치 블록이 실행되도록 예약 된 뷰 계층에 있다고 보장하는 문서화 된 보증을 보지 못했지만 제대로 작동한다는 것을 관찰했습니다.

예를 들어 0.2 초의 지연을 사용하는 것도 옵션입니다. 그리고 가장 좋은 방법-부울 변수를 엉망으로 만들 필요가 없습니다.viewDidAppear:


2
이것이 지금 작동 할 수도 있지만, Apple이 나중에 행동을 변경하여이를 위반할 것이라는 보장은 없습니다. 그런 다음 코드를 살펴보고 다시 시도하여 문제를 해결하면 왜 불필요한 것처럼 보이는 파견을했는지 궁금 할 것입니다.
Cruinh

0 시간의 디스패치는 이미 많은 시간을 절약했습니다. 때로는 논리적으로 작동 해야하는 것이 정상적으로 작동하지 않는 경우가 있습니다. 따라서 왜 자신이 불분명 한 일 (그러한 파견뿐만 아니라)을하는지에 대해 자신과 다른 사람들에게 의견을 말하면 괜찮을 것입니다.
Dannie P

2
문제를 해킹하고 해결하지는 않습니다.
마이클 피터슨

0

탐색 컨트롤러를 사용할 수있는 경우 모든보기 컨트롤러를 표시합니다. self.navigationController? .present (MyViewController, animated : true, complete : nil) 또한 경고 및 메일 컨트롤러를 표시 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.