Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

qx11

macrumors newbie
Original poster
Oct 18, 2013
2
0
I have a program that runs through a while loop and updates some UILabels. However, the UILabels do not actually appear updated. Here is the while loop that updates the labels:

Code:
- (void)runSimulation {
    [theModel randomize:50];
    simulationPaused = false;
    while(!simulationPaused) {
        [theModel calculateNextGeneration];
        [theView updateCells];
    }
}

The "updateCells" function is the one that actually updates the UILabels, with the following line:

Code:
                ((UILabel*)[[labelArray objectAtIndex:i] objectAtIndex:j]).backgroundColor = [UIColor grayColor];

However, when I add the following code to the end of the while loop of "runSimulation":

Code:
	simulationPaused = true;

then the UILabels are updated as I expected. I am guessing that the program will not update a UILabel while it is going through a while loop. How can I make the program update the UILabels during a while loop?
 

dantastic

macrumors 6502a
Jan 21, 2011
572
678
You need to break out of the run loop for the UI to update. You really shouldn't be using a tight loop like that to update the UI. For a quick and dirty you can do



Code:
- (void)runSimulation {
    [theModel randomize:50];
    simulationPaused = false;
    while(!simulationPaused) {
        [theModel calculateNextGeneration];
        [theView performSelectorOnMainThread:@selector(updateCells) withObject:nil waitUntilDone:YES];
    }
}
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
You need to break out of the run loop for the UI to update. You really shouldn't be using a tight loop like that to update the UI. For a quick and dirty you can do



Code:
- (void)runSimulation {
    [theModel randomize:50];
    simulationPaused = false;
    while(!simulationPaused) {
        [theModel calculateNextGeneration];
        [theView performSelectorOnMainThread:@selector(updateCells) withObject:nil waitUntilDone:YES];
    }
}

To be clear, that code would have to be run on a background thread in order to solve the OPs problem.
 

firewood

macrumors G3
Jul 29, 2003
8,106
1,343
Silicon Valley
I
am guessing that the program will not update a UILabel while it is going through a while loop. How can I make the program update the UILabels during a while loop?

Exit the while loop and the method that contains the while loop. Then the run loop will update the UI display. You can get back to the rest of the code in and after the while loop using a timer or completion callback.
 

qx11

macrumors newbie
Original poster
Oct 18, 2013
2
0
I tried using 'performSelectorOnMainThread...' but it still did not work. I suspect that what I'm doing is not the best way to do what I'm trying to do. What I'm trying to do is simulate Conway's game of Life on iOS. I am using a UILabel to represent each cell and then I change the background color of each cell with each generation to change the cell to be on or off. Should I not be using UILabels to represent cells that change frequently?
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
I tried using 'performSelectorOnMainThread...' but it still did not work. I suspect that what I'm doing is not the best way to do what I'm trying to do. What I'm trying to do is simulate Conway's game of Life on iOS. I am using a UILabel to represent each cell and then I change the background color of each cell with each generation to change the cell to be on or off. Should I not be using UILabels to represent cells that change frequently?

performSelectorOnMainThread only does something different when it is run from a background thread. If you run that code on the main thread, it doesn't do any good.

You should most definitely NOT be using a grid of labels to represent cells in the game of life. That is really inefficient. You'd be better off with a custom object that overrides it's drawRect method to draw the cells using Cocoa drawing commands.
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Common ways to update UI periodically are to use an NSTimer or use performSelector:withObject:afterDelay.

If you use the timer set it to run periodically. When it calls your code back you update the views once and then return. It will call you back time after time until you stop it.

If you use performSelector you need a method that updates your UI one time. At the end of that method use performSelector:withObject:afterDelay: to make it call your code back after the specified delay.

Both of those cases will call your code back on the main thread, which is probably what you want.

Drawing on iOS only happens when your code isn't running on the main thread.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.