简体   繁体   中英

iOS: change view from viewDidAppear

I'm playing around with view life cycles & am having trouble changing a view from the load of a different view.

In my ViewController.hi have:

-(void)viewDidAppear:(BOOL)animated{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ViewController2 *viewController = (ViewController2 *)[storyboard instantiateViewControllerWithIdentifier:@"ViewController2"];
    [self presentViewController:viewController animated:YES completion:nil];
}

However this only causes the view to be between ViewController, and ViewController2 appearing with animation (in a loop).

I used the code in viewDidLoad however neither of the view's loaded (from reading you cannot change view until the viewWillAppear)

Update: When using the code in viewWillAppear , whose view is not in the window hierarchy error is thrown.

How does one change the view from view setup stage?

Using the above code, inside & out of GCD, in viewDidLoad , viewWillAppear & viewDidAppear either results in an infinite loop of animated showing of the ViewController2, or crash on 2nd attempt of segue (result from the loop). 使用上述代码,在GCD内部和外部,在viewDidLoadviewWillAppearviewDidAppear要么导致ViewController2的动画显示无限循环,要么导致第二次segue尝试崩溃(从循环中得到)。

EDITED:

I'm not sure exactly what you're trying to do, but assuming you are wanting the first viewcontroller to appear and then the second viewcontroller to immediately animate on top of the first one, you should be able to accomplish using several options:

First you could just wrap your calls in a dispatch_async call:

dispatch_async(dispatch_get_main_queue(), ^{

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ViewController2 *viewController = (ViewController2 *)[storyboard 
    instantiateViewControllerWithIdentifier:@"ViewController2"];

    [self presentViewController:viewController animated:YES completion:nil];
});

Or you could use a show modally segue:

- (void)viewDidLoad {
  [super viewDidLoad];

  dispatch_async(dispatch_get_main_queue(), ^{

        [self performSegueWithIdentifier:@"myModalSegue" sender:self];
  });
}

Or you could use a navigation controller and use a standard show segue (formally push). This one doesn't require the dispatch_async:

- (void)viewDidLoad {
  [super viewDidLoad];

  [self performSegueWithIdentifier:@"myshowsegue" sender:self];
}

I've posted working examples of all three on: github

It is better to exchange views in loadView method.

- (void)loadView {
    CGRect rect = [[UIScreen mainScreen] applicationFrame];
    MyView *view = [[MyView alloc] initWithFrame:rect];
    [view setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
    self.view = view;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM