Max Ka
Max Ka

Reputation: 552

UIViewController loading after delay

I'm having some really weird behavior in my UIViewController. I'm connecting two devices via the Multipeer Framework and once a iPhone starts sending data I want the other iPhone to display a UIViewController which handles the received data. So once iPhone A starts sending, iPhone B posts a NSNotification. The notification is arriving pretty fast and the code below is being executed:

- (void)presentPeerView:(NSNotification *)notif
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ClientViewController *clientView = (ClientViewController *)[storyboard instantiateViewControllerWithIdentifier:@"peerView"];
    [clientView setImage:_image];
    clientView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.window.rootViewController presentViewController:clientView animated:YES completion:nil];
}

Now here comes the weird part. First of all, the ClientViewController gets displayed. But there is no animation, it just appears out of nowhere. My viewDidLoad gets called and runs following code:

- (void)viewDidLoad
{
    [self.view setBackgroundColor:[UIColor colorWithPatternImage:[self blurImage:_image];
    [self.imageView setImage:_image];        
}

Now, I see the blurred image, which is fine. But the (non blurred) image dosen't displays in the UIImageView. I mean the image get's passed properly, otherwise I couldn't see the blurred Background. I also have a few Interface elements from the Storyboard:

Screenshot from Storyboard

So the UIViewController loads with the blurred background Image:

blurred Background example

As you can see, none of the Storyboard UI Elements are loaded, except for the UISwitch (which looks quite strange, too). After a couple of seconds (it depends, sometimes up to 30, sometimes only 3 seconds) the whole UI loads up: Whole UI after some time

So, maybe someone of you had the same issue before, I really don't understand why the UI does take so much time to "load". The CPU percentage is somewhere around 3%.

I also added a NSLog() to the this completion block:

[self.window.rootViewController presentViewController:clientView animated:YES completion:^{
NSLog(@"done.");
}];

which is called instantly. The viewDidLoad seems to work fine, there are no lines it might get stuck, if I do a NSLog at the end of viewDidLoad it gets called instantly as well, but the view (as you can see in the images below) isn't loaded (completely).

Upvotes: 0

Views: 782

Answers (1)

Aaron Brager
Aaron Brager

Reputation: 66244

From the MCSession class reference:

Important: Delegate calls occur on a private operation queue. If your app needs to perform an action on a particular run loop or operation queue, its delegate method should explicitly dispatch or schedule that work.

You're seeing this delay because you're doing UIView work on the wrong thread.

There's a number of ways to fix this, for example:

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {
    dispatch_async(dispatch_get_main_queue(), ^{
        // post your notification or display your view
    });    
}

Upvotes: 2

Related Questions