PDA

View Full Version : Force update UIView




alvises
Jul 15, 2008, 02:26 PM
Hi,

in my application I have a thread that receives data from a tcp connection. It manages some Outlets like UITextView updating the text. The problem is when the thread modifies the text of a UITextView object, doesn't update the screen. This because the thread doesn't return to the Application Run Loop.
A pseudo code


while(running){
NSString *line = [self receive];
//console is UITextView
console.text = line;
}



The problem is that "console" object doesn't update :(
What can i do ? The "setNeedDisplay" doesn't work too.

Thanks a lot.

Alvise



detz
Jul 15, 2008, 04:08 PM
I asked on here a similar question the other day, no response. What I did(might not be the best way) is start a timer that does the long process that when it's done updates the screen back.

DaveGee
Jul 15, 2008, 04:39 PM
I think you need to look into NSThread to do what you need... and then setup some kind of 'call back to the main thread' (from the 'other thread') when you want to have a refresh... I've go something 'kinda working' that does just that but I'm sure its not the right way to do it so I'm afraid to even post the code. It's really messy and it would be hard to break it out to an easy to digest example.

In short...

I 'thread off' code that listens to a TCP socket and gathers data... I then return to the main thread and continue on my apps merry way...

When the 'thread' gets data it calls back to the main thread where it 'does stuff' (updates an NSMutableArray in my case) and then does a refresh of the table.

Dave

alvises
Jul 16, 2008, 04:00 AM
Thank you !!
Do you mean that if before i did something like :

-(void)mainloop{
while(running){
NSString *line = [self getLine];
console.text = line;
}
}

To return to mainloop i can do something like


-(void)functionInMainThread{

[NSTimer secheduled...... @selector(newMainloop) repeats:YES];

}

-(void)newMainloop:(NSTimer*)timer{
NSString *line = [self getLine];
console.text = line;
}



Could work ?
Thanks

Alvise

alvises
Jul 16, 2008, 04:04 AM
Thank you !!
Do you mean that if before i did something like :

-(void)mainloop{
while(running){
NSString *line = [self getLine];
console.text = line;
}
}

To return to mainloop i can do something like


-(void)functionInMainThread{

[NSTimer secheduled...... @selector(newMainloop) repeats:YES];

}

-(void)newMainloop:(NSTimer*)timer{
NSString *line = [self getLine];
console.text = line;
}



Could work ?
Thanks

Alvise




YEAAA !!! It Works !!!! Thanks a lot !!


Alvise

detz
Jul 16, 2008, 06:45 AM
I would think there would be an updateView function because not my code is filled with useless 0.1 second timers. :mad:

alvises
Jul 17, 2008, 03:49 AM
I would think there would be an updateView function because not my code is filled with useless 0.1 second timers. :mad:

Detz, now I write a general subclass of UIView that works as "Update Manager" After that I will post it to the forum ;)

detz
Jul 17, 2008, 06:20 AM
Another way you can do it is to animate the item you want changed. If you animate it it some way(not even visible) the app will start a new animation thread for you and refresh you item.

[UIView beginAnimations:nil context:nil];
...
[UIView commitAnimations];

alvises
Jul 17, 2008, 07:40 AM
Another way you can do it is to animate the item you want changed. If you animate it it some way(not even visible) the app will start a new animation thread for you and refresh you item.

[UIView beginAnimations:nil context:nil];
...
[UIView commitAnimations];

Thanks ! Could be useful!!

alvises
Jul 17, 2008, 11:11 AM
Another annoying problem ...
This code is a mainloop

-(IBAction)startMainloop:(id)sender{
messengerController = [[MulodMessengerController alloc] init];
[NSTimer scheduledTimerWithTimeInterval:0.01 target:messengerController selector:@selector(mainloop:) userInfo:nil repeats:YES];
}


The timer is like a "while" that loops the mainloop method. Mainloop waits to read from TCP socket.
The view is updated(!!) BUT the interaction is TOTALY LOCKED. The user can do NOTHING :(
What i can do.. why there is no method to force the update manually ? Or a message event to send to runLoop to update the screen..
Thanks.

Alvise

firewood
Jul 17, 2008, 11:56 AM
Look at animation game engine code examples, or the Accelerometer demo app. They update the display 10 to 30 times per second (no need to do so faster) with the latest data, if needed.

The trick seems to be to set a timer in the main loop to periodically send setNeedsDisplay to the current view controller, and then check in that view controller's drawRect for anything that needs updating. Don't set the timer to faster than you can update on average or your frame rate will drop and/or the device will lock up.

alvises
Jul 17, 2008, 01:39 PM
Seems that i need to manage all the gui manually :| Isn't there something simple like "window.display" lile macos X cocoa ?

incorrect.user
Aug 19, 2008, 11:59 AM
I've almost the same problem:

After clicking on a button in a corresponding action i create a new thread in which make a socket connection and download some data. After each portion of data i add some messages to a UITextView and ofcourse they do not appear immediately (only after that thread returns). :(

Help, please

incorrect.user
Aug 20, 2008, 05:26 AM
Here's the solution:

- (void) thread
{
//....
[self performSelectorOnMainThread: @selector(refresh_textview: ) withObject:@"Some text that u need to output into the UITextview" waitUntilDone:NO];
//....
}

- (void)refresh_textview: (NSString*)text
{
[textview setText:text];
}

:rolleyes:;):):D