Why is viewDidLoad waiting until the user interface is updated?

I'm just trying to plunge into the Objective-C event model on the iPhone, and looking at things that I fundamentally misunderstood here.

For experimental purposes, in viewviewDoadLoad controller mode, I set the text to UILabel, then sleep for two seconds, and then change the label text again.

My expectations are as follows: the label will read “First Text” first, then after two seconds it will be updated to read “Second Text”. Of course, this is not quite the way it happens. Instead, the view is not displayed at all for two seconds, and finally, when it becomes visible, its label reads "Second Text".

Can someone please explain to me what is going on? I am interested to know how you guys will achieve what I'm going to do here.

Greetings.

UPDATE 1 : here is the viewDidLoad method:

- (void)viewDidLoad { [super viewDidLoad]; label.text = @"First Label"; sleep(2); label.text = @"Second Label"; } 

UPDATE 2 . I made a stupid mistake, so please ignore this update.

UPDATE 3 : I have now added the following to my viewDidAppear method:

 - (void)viewDidAppear: (BOOL)animated { [super viewDidAppear: animated]; label.text = @"First Label"; sleep(2); label.text = @"Second Label"; } 

Unfortunately, I have exactly the same problem.

UPDATE 4 : after the offers of gerry3 and Felix, I now implemented the Performer function and boom! Working! I will have to give it to gerry3, although he certainly does his best to help me. Thanks for all your contributions!

+3
objective-c iphone
source share
4 answers

Put your code that changes view in viewDidAppear:

The view is not yet displayed when viewDidLoad and viewWillAppear: called.

UPDATE
To be clear, I agree with others that the correct way to do this is with a method call delay or a timer.

UPDATE 2
Here is the code I suggest:

 - (void)viewDidLoad { [super viewDidLoad]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSLog(@"View will appear!"); } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSLog(@"View did appear!"); label.text = @"First Label"; sleep(2); label.text = @"Second Label"; } 

And the "right" way:

 - (void)viewDidLoad { [super viewDidLoad]; label.text = @"First Label"; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSLog(@"View will appear!"); } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSLog(@"View did appear!"); [self performSelector:@selector(changeLabelText) withObject:nil afterDelay:2.0f]; } - (void)changeLabelText { label.text = @"Second Label"; } 
+3
source share

I think the reason is that viewDidLoad works on mainThread, like all UIKit interactions. The user interface can only be updated on mainThread, so if you block viewDidLoad with sleep(2) , you put mainThread in sleep mode and stop all user interface updates in this thread.

Use NSTimer if you want to update the user interface after a certain time, instead of using sleep(2) . Or use performSelector:withDelay: to execute the method yourself later without blocking mainThread.

The same is true for viewDidAppear and viewWillAppear . Both run on mainThread.

+4
source share

I do not think that you really want to cause a dream in this method. This is what you should try and use a timer to avoid blocking the user interface and the entire application. A timer allows you to call code only once or several times. See the manual for more information.

0
source share

The signature viewDidAppear and viewWillAppear is incorrect in your example. They should be

 - (void)viewWillAppear: (BOOL)animated { NSLog(@"View will appear!"); } -(void)viewDidAppear : (BOOL)animated { NSLog(@"View did appear!"); } 

Frames will not call implementations with the wrong signature, because sending messages does not find them.

0
source share

All Articles