code

ViewDidLoad에서 Segue 수행

codestyles 2020. 12. 27. 10:54
반응형

ViewDidLoad에서 Segue 수행


iOS 5에는 모달 뷰 컨트롤러가있는 스토리 보드가 있는데, 사용자가 앱에서 처음 인 경우이 뷰 컨트롤러를 건너 뛰고 싶습니다.

이를 처리하기 위해 NSDefault 키를 설정했지만 이것이 설정되었는지 확인한 다음 performSegueWithIdentifier를 사용하여 segue를 시작하면 아무 일도 일어나지 않습니다. 이 segue를 버튼 뒤에 넣으면 잘 작동합니다 ...


개발자가 처음에 로그인 화면을 표시하고 싶은 비슷한 질문에 대답했습니다. 여기에서 다운로드 할 수있는 몇 가지 샘플 코드를 모았 습니다 . 이 문제를 해결하는 열쇠는이 새로운 뷰 컨트롤러를 표시하고 싶다면 적시에 호출하는 것입니다. 예제에서 다음과 같은 것을 사용해야합니다.

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

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
    [vc setModalPresentationStyle:UIModalPresentationFullScreen];

    [self presentModalViewController:vc animated:YES];
}

또한 여기에서 볼 수있는 segues 및 storyboards 작동 방식에 대한 설명이 있습니다.


ViewDidLoad에서로드하면 "언더 레이어"가 깜박입니다. 내 스토리 보드를 프로그래밍 방식으로로드하여이 문제를 해결했습니다. 따라서 Target / Main Storyboard에서이 항목을 비워 둡니다. 그런 다음 다음을 추가하십시오.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Load Main App Screen
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    HomeScreenVC *homeScreenVC = [storyboard instantiateInitialViewController];
    self.window.rootViewController = homeScreenVC;
    [self.window makeKeyAndVisible];

    // Load Login/Signup View Controller
    UIViewController *mainLoginVC = [storyboard instantiateViewControllerWithIdentifier:@"MainLoginVC"];
    [mainLoginVC setModalPresentationStyle:UIModalPresentationFullScreen];
    [homeScreenVC presentModalViewController:mainLoginVC animated:NO];

    return YES;
}

문제는 첫 번째 뷰가 완전히 추가되기 전에 계층 구조에 두 번째 뷰를 추가한다는 것입니다. 코드를 넣으십시오.

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    // Present your modal from here
}

[super viewDidAppear]이 호출 된 후에 는 수정할 수있는 완전히로드 된보기가 있습니다.


viewDidLoad (물론 super를 호출 한 후)에서 segues를 수행하는 데 주요한 문제는 없습니다.

문제는 응용 프로그램 창이 표시되기 전에 segues를 수행하는 것입니다. 표시하려는 UIViewController는 메인 스토리 보드의 일부이므로 앱이 앱 델리게이트에서 코드 실행을 시작하기 전에 메모리에로드됩니다. 귀하의 경우 애플리케이션 창에 MakeKeyAndVisible 메시지가 표시되기 전에 iOS에서 viewDidLoad를 호출합니다.

중요한 부분은 가시성입니다. 창이 보이지 않는 뷰 계층 구조에서 segue를 수행하면 아무 일도 일어나지 않습니다!

다음과 같이 시도 할 수 있습니다.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// The window initialized with hidden = YES, so in order to perform the segue we need to set this value to NO.
// After this action, the OS will add the window.rootViewController's view as a subview of the window.
self.window.hidden = NO;

[self.window.rootViewController performSegueWithIdentifier:_IDENTIFIER_ sender:self.window.rootViewController];

// Now that the window is not hidden, we must make it key.
[self.window makeKeyWindow];
return YES;
}

업데이트 : 이 솔루션은 더 이상 iOS 8에서 작동하지 않습니다.

문제를 해결하는 올바른 방법은 applicationDidBecomeActive:앱 델리게이트 메서드 또는 UIApplicationDidBecomeActiveNotification알림 핸들러 에서 segue / present 모달 뷰 컨트롤러를 트리거하는 것 입니다.

Apple의 문서는 실제로 다음과 같이 조언합니다 .

앱이 이전에 백그라운드에 있었다면이를 사용하여 앱의 사용자 인터페이스를 새로 고칠 수도 있습니다.

이 솔루션은 메인 스토리 보드로드 메커니즘과 함께 작동하므로 수동으로로드하고 불필요한 코드를 작성할 필요가 없다는 이점이 있습니다.

이 솔루션은 iOS 6.1, 7.0 및 7.1에서 성공적으로 사용되며 iOS 5에서도 작동합니다.


이것이 제가 SWIFT에서 한 방법입니다. 이것은 또한 View Controller를 숨 깁니다.

override func viewWillAppear(animated: Bool) {
    let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
    if (isloggedIn != false) {
        self.view.hidden = true
    } else {
        self.view.hidden = false
    }
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(true)

    let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
    if (isloggedIn != false) {
        println("this should work")
        self.performSegueWithIdentifier("Login", sender: self)
    }
}

Swift의 경우 :

dispatch_async(dispatch_get_main_queue()) {
   self.performSegueWithIdentifier("toView2", sender: self)
}

Swift 3 :

DispatchQueue.main.async {
    self.performSegueWithIdentifier("toView2", sender: self)
}

스위프트 3

override func viewWillAppear(_ animated: Bool) {
    if authPreference.isExist() == true {
        self.view.isHidden = true
    } else {
        self.view.isHidden = false
    }
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)

    if authPreference.isExist() == true {
        navigateToSegue()
    }
}

나는 같은 문제가 있었다. 이 질문을 찾기 전에 주 스레드에서 비동기를 사용하여이 문제를 해결했습니다. 이렇게하면 뷰를 생성 한 직후 UI 스레드에서이 코드를 호출합니다.

dispatch_async(dispatch_get_main_queue(), ^{
        [self performSegueWithIdentifier:@"segueAlbums" sender:self];
    });

이 코드는 viewDidLoad메서드 에서 호출 할 수 있습니다 .


Swift 3 업데이트

The code snippet below allows you to load whichever viewController you want. In my case it was a TabBarController if the user had a valid facebook login token. The benefit to this solution over the other Swift 3 solution is that it's instantaneous with no screen flicker.

func applicationDidBecomeActive(_ application: UIApplication) {
    if FBSDKAccessToken.current() != nil {
        self.window?.rootViewController?.present((self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "TabBarController"))!, animated: false, completion: nil)           
    }
}

The best solution is to do this:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];    
    [self performSegueWithIdentifier:@"NameSegue" sender:self];
}

I adapted @bearMountain answer for Swift 3.

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    let yourInitialVC: UIViewController? = storyboard.instantiateViewController(withIdentifier: "TermsVC")
    window?.rootViewController = termsVC
    window?.makeKeyAndVisible()
    return true
}

ReferenceURL : https://stackoverflow.com/questions/8221787/perform-segue-on-viewdidload

반응형