satyanarayana
satyanarayana

Reputation: 275

ViewDidLoad executes slowly while pushing viewcontroller

I was trying to push a viewcontroller B into navigation controller from A and then assigning some properties of B in A.
In this case, the assigning of properties was done and then viewDidLoad of viewcontroller A was executed.

Here, assigning properties in A should be done only after viewDidLoad of A has done.

For example,

[b.navController pushViewController:a animated:YES];
a.status = @"loaded";

Here, status was assigned first and then viewDidLoad of A was executed. This happens only in iOS 7 whereas in iOS6 it works fine.

Can anyone please let me know where the problem is?

UPDATE: For me in some cases in iOS7, Push view is not working. How cna I debug and fix it?

Upvotes: 6

Views: 3350

Answers (8)

Raviraj Jadeja
Raviraj Jadeja

Reputation: 849

Please write the code in viewWillAppear method instead of viewDidLoad in next class i.e. where you are pushing the object to

-(void)viewWillAppear:(BOOL)animated
{

}

Upvotes: 0

Gian Franco Zabarino
Gian Franco Zabarino

Reputation: 432

In my experience, a UIViewController view is loaded lazily, no matter which iOS version you're working on. If you want to trigger a view load, and therefore its UIViewController viewDidLoad, you should access the view after the UIViewController is allocated. For example:

UIViewController *aViewController = [[CustomViewController alloc] init];
[aViewController view];

Make sure you don't code it as

aViewController.view

since that would generate a compiler warning.

So, in your case it would have to be something like this:

...
CustomViewController *a = [[CustomViewController alloc] init];
[b.navController pushViewController:a animated:YES];
[a view];
a.status = @"loaded";

Let me know if you have further problems with it.

Upvotes: 1

Abhinit
Abhinit

Reputation: 1016

No documentation provides enough information to know exactly when viewDidLoad would be called.

UIViewController's documentation just says this

This method is called after the view controller has loaded its view hierarchy into memory

I would suggest that you create a custom initializer like this

- (id)initWithStatus:(NSString *)status {
}

But, if you are trying to use this variable to check if the viewController's view has 'loaded' or not, it may not be possible to do that because the pushViewController or presentViewController methods are not guaranteed to be synchronous.

Even in iOS 6, there was no explicit guarantee that the view would be loaded as soon as that method returned.

Upvotes: 0

Divya Bhaloidiya
Divya Bhaloidiya

Reputation: 5064

Turn off animation for ios7, in my case its work

[b.navController pushViewController:a animated:NO];
a.status = @"loaded";

Upvotes: 0

Lirik
Lirik

Reputation: 3197

I would suggest you call a delegate method once the view is loaded. Set the delegate to be controller B. and after viewDidLoad finishes (in controller A) call the delegate method. You can even pass parameters as you wish to the delegate.

Here's some example code:

Controller B:

a.delegate = self;
[b.navigationController pushViewController:a animated:YES];

Implement the delegate method:

- (void)controllerIsLoaded:(ControllerA *)controllerA status:(NSString *)status
{
    a.status = status;
}

Controller A .h file:

@class ControllerA;

@protocol ControllerADelegate <NSObject>
- (void)controllerIsLoaded:(ControllerA *)controllerA status:(NSString *)status;
@end

@interface ControllerA : UIViewController 

@property (nonatomic, weak) id <ControllerADelegate> delegate;

Controller A .m file:

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

    /* your viewDidLoad code here... */

    if ([_delegate respondsToSelector:@selector(controllerIsLoaded:status)])
        [_delegate controllerIsLoaded:self status:@"Loaded"];
}

Upvotes: 0

Muthu Sabarinathan
Muthu Sabarinathan

Reputation: 1208

I'm understand of your question like this:

B *b = [[B alloc] init];
b.status = @"loaded";
[self.navigationController pushViewController:b animated:Yes];

If you want to pass a value from one controller to another means, you have to assign a value before using pushViewController method.

Upvotes: -1

Darren
Darren

Reputation: 10398

You can know when a View Controller has been pushed onto the stack by implementing the UINavigationControllerDelegate and setting yourself as the delegate self.navigationController.delegate = self; then you will get this callback after every push

navigationController:didShowViewController:animated:

So you can check if the shown viewController is the one your interested in, then set your a.status.

Upvotes: 0

Hiren
Hiren

Reputation: 689

Just access the viewcontroller.view (set any thing immediately after the alloc) property after the alloc init;

Which will loadview/viewdidload.
See Apple Documentation

Upvotes: 1

Related Questions