Force update UIView

Discussion in 'iPhone/iPad Programming' started by alvises, Jul 15, 2008.

  1. macrumors newbie

    Joined:
    Jul 15, 2008
    #1
    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
     
  2. macrumors 65816

    Joined:
    Jun 29, 2007
    #2
    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.
     
  3. macrumors 6502a

    Joined:
    Jul 25, 2001
    #3
    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
     
  4. thread starter macrumors newbie

    Joined:
    Jul 15, 2008
    #4
    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
     
  5. thread starter macrumors newbie

    Joined:
    Jul 15, 2008
    #5



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


    Alvise
     
  6. macrumors 65816

    Joined:
    Jun 29, 2007
    #6
    I would think there would be an updateView function because not my code is filled with useless 0.1 second timers. :mad:
     
  7. thread starter macrumors newbie

    Joined:
    Jul 15, 2008
    #7
    Detz, now I write a general subclass of UIView that works as "Update Manager" After that I will post it to the forum ;)
     
  8. macrumors 65816

    Joined:
    Jun 29, 2007
    #8
    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];
     
  9. thread starter macrumors newbie

    Joined:
    Jul 15, 2008
    #9
    Thanks ! Could be useful!!
     
  10. thread starter macrumors newbie

    Joined:
    Jul 15, 2008
    #10
    Another annoying problem ...
    This code is a mainloop

    -(IBAction)startMainloop:(id)sender{
    messengerController = [[MulodMessengerController alloc] init];
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:messengerController selector:mad: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
     
  11. macrumors 603

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #11
    animation code

    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.
     
  12. thread starter macrumors newbie

    Joined:
    Jul 15, 2008
    #12
    Seems that i need to manage all the gui manually :| Isn't there something simple like "window.display" lile macos X cocoa ?
     
  13. macrumors newbie

    Joined:
    Aug 19, 2008
    #13
    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
     
  14. macrumors newbie

    Joined:
    Aug 19, 2008
    #14
    Here's the solution:

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

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

    :rolleyes:;):):D
     

Share This Page