3
votes

I have just moved my iOS 5 project to iOS 6 environment (since Apple made it mandatory to support 4-inch device compability) and now I am having a bit of a problem while pushing a UIViewController on to UINavigationController.

After I push my custom UIViewController, my user interface blocks for 5 to 20 seconds, only when I am pushing that custom UIViewController for the first time. If I pop my UIViewController and push it again, there is no delay or UI block.

Here is what happens;

First I am pushing my UIViewController from UITableViewController's didSelectRowAtIndexPath (custom init works fine, no issue there)

CampaignDetailViewController *detailViewController = [[CampaignDetailViewController alloc] initWithProduct:selectedProduct];
    [self.navigationController pushViewController:detailViewController animated:YES];

Than I am logging everything (I cleared all code in viewDidLoad, viewWillAppear and viewDidAppear, which means pushing the controller should only load nib)

On the pushed UIViewController;

- (id)initWithProduct:(Product *)selectedProduct
{
    NSLog(@"starting init");
    self = [super initWithNibName:@"CampaignDetailViewController" bundle:nil];
    NSLog(@"nib loaded");
    if (self) {
        self.navigationItem.title = selectedProduct.name;
        self.product = selectedProduct;
    }
    NSLog(@"finishing init");
    return self;
}

- (void)viewDidLoad
{
    NSLog(@"starting viewdidload");
    [super viewDidLoad];
    NSLog(@"finishing viewdidload");
}

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"view will appear");
}

- (void)viewDidAppear:(BOOL)animated
{
    NSLog(@"view did appear");
}

Debugger Log;

2013-05-03 12:33:49.678 my-app[1429:707] starting init
2013-05-03 12:33:49.680 my-app[1429:707] nib loaded
2013-05-03 12:33:49.683 my-app[1429:707] finishing init
2013-05-03 12:33:49.808 my-app[1429:707] starting viewdidload
2013-05-03 12:33:49.855 my-app[1429:707] finishing viewdidload
2013-05-03 12:33:49.861 my-app[1429:707] view will appear
2013-05-03 12:35:28.501 my-app[1429:707] view did appear

There is over 30 seconds of delay between viewWillAppear and viewDidAppear.

Further Info

  • I have tried to use regular init and removed the nib file, nothing changed.
  • Nothing gets loaded in between of pushViewController and loading the UIViewController.
  • This issue happens on my iPhone 4 - iOS 5 device. Everything works fine on iOS 5 and 6 simulators also works fine on my iPhone 5 - iOS 6 device.
  • I am pushing other view controllers on other parts of my project as well, but this UIViewController seems to be the only issue.
  • View controller is pushed on the main thread, and therefore view controller is loaded on the main thread
  • During this blocked period, XCode (4.6.1) also gets blocked and does not responds as well
4
upgrade your iphone to ios 6 version, or set ios 5 compatibility in your project setting - Nagasaki
instead of 'super' in self = [super initWithNibName:@"CampaignDetailViewController" bundle:nil]; why don't u use 'self' like [self initWithNibName:@"CampaignDetailViewController" bundle:nil]; - Ishank
@Nagasaki deployment target is set to iOS 5.0. Is there anything else to be set? - Bartu
@Ishank that would be pretty much same with what I did, since selfs initWithNibName calls super and returns it, which only means +1 call - Bartu
Are you doing this all on the main thread? - Mike Weller

4 Answers

4
votes

Two hints:

1 - is this issue happening on the simulator or on a real device? I've experienced many unexpected delays on the simulator.

2 - remember to call

[super viewWillAppear:animated];

and

[super viewDidAppear:animated];

inside the impelentations.

From Apple documentation:

If you override this method, you must call super at some point in your implementation.

0
votes

Be careful when you are executing UI code inside blocks, this should run inside main thread! If you do not you can be affected by this kind of behaviour or worse as UIKit is not thread safe.

__weak CurrentViewController *wSelf = self;    
dispatch_async(dispatch_get_main_queue(), ^{
        [wSelf.navigationController pushViewController:wSelf.someController animated:YES];
});
0
votes

I found the issue, i had the same problem and it was quite hidden bug. I had upgraded my project and some .xib files were not upgraded correctly. On interface builded select the .xib and check the project deployment target to be the last one and also opens in to be the default one (mine was stuck on very old version while the rest were updated)!

enter image description here

0
votes

In my case problem was with UILabel with shadow.