views:

143

answers:

3

Hey guys,

I am currently working on a project where I request and parse multiple html sites in a controller. To give some feedback to the user I have created a second view, which gets displayed during processing of the data. It displays a status label and a progressbar. In my controller I have several points where I update my labels text. Unfortunately this works only sometimes. I guess thats because the label gets redrawn only once in a while and I try to do it probably more often than once a second.

It does not work to force a redraw with [label setNeedsDisplay];

I also made a thread which updates the labels text with the text of a global variable and also calls setNeedsDisplay on the label every second. But the results in the same. I only see certain changes, but not all.

Everything is setup properly and the label never is nil. When I log my updateMethod everything seems allright. It just does not get displayed!

Cheers

Here is the code of my threads

- (void)startUpdateStatusThread{

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
[self performSelectorOnMainThread:@selector(updateFrequently) withObject:nil waitUntilDone:NO];
[pool release];
}



- (void)updateFrequently{
NSLog(@"updateFrequently: %@", currentStatus);
test++;
[self.statusLabel setText:[NSString stringWithFormat:@"%@ - %i", currentStatus, test]];
[self.statusLabel setNeedsDisplay];
[NSTimer scheduledTimerWithTimeInterval:0.0001 target:self   selector:@selector(updateFrequently) userInfo:nil repeats:NO];
}
A: 

You mention threads. Be aware that UIKit controls, such as UILabel, can only be updated from the main thread. Make sure you are only attempting to set the label's text from the main thread and then verify if you are still having issues.

EDIT due to question edit:

First, -setNeedsDisplay only tells the view it needs to redisplay the next time the screen is refreshed, it does not force a display at that time.

Second, the iPhone screen draws at about 60 hz. This means there is an update every 0.016666 or so seconds. You're trying to update much faster than that, so only about every 160th of your updates will actually be displayed.

Third, and probably most important, you don't seem to be making any threads, unless you call -startUpdateStatusThread from a background thread. Either way, once you hit -updateFrequently everything is back on the main thread. With the frequency you are scheduling that timer, you are probably overloading the CPU and making it so that the system does not have time to draw the label. So even though you are setting new text, you aren't giving it a chance to render. You need to reduce the frequency of that timer, and you probably need to rethink whatever it is you're trying to do.

Jason Foreman
See the edit in the question above
jagse
A: 

Hi there, Am I right if I assume that you call your label's text-property as well as setNeedsDisplay from within your "Thread" that is parsing your websites?

Note that: changes to UIViews (or subclasses of UIView like your label) must be performed on the main thread.

What I recommend you to do is write a helper method that updates your label and calls setNeedDisplay, the from within your Parser-Thread call [mainViewController performSelectorOnMainThread:@selector(yourUpdateLabelHelper:) withObject:nil waitUntilDone:NO];

that should get your job done.


cheers
sam

samsam
See the edit in the question above
jagse
A: 

I think that the creation of the timer should be in separate function: Allow the repetition and also store the timer in a member variable you can close on dealloc. [NSTimer scheduledTimerWithTimeInterval:0.0001 target:self selector:@selector(updateFrequently) userInfo:nil repeats:YES]; }

The update function should operate as a callback function.

Regards Assayag

Meir Assayag