Trouble setting label text in iOS

2020-02-06 18:18发布

I have a connected UILabel

@property (strong, nonatomic) IBOutlet UILabel *label;

And an Action, which is triggered by the button

- (IBAction)buttonPressed:(UIButton *)sender;

When button is pressed, i'd like to update the label to display running seconds up to 3 minutes, so i

- (IBAction)buttonPressed:(UIButton *)sender {
    for (int i =0; i < 180; ++i) {
        [label setText:[NSString stringWithFormat:@"%d", i]];
        sleep(1);
    }
}

Confirmed, method is called, timer is ticking ..the label text however does not change. What am i doing wrong please?

4条回答
叼着烟拽天下
2楼-- · 2020-02-06 18:27

your sleep() is in the main thread , your view cannot refresh , you can ues NSTimer to do it.

- (void)update
{
    [label setText:[NSString stringWithFormat:@"%d", i]];
    i++;
    if(i>=100)
    {
        [timer invalidate];
    }
}

- (IBAction)buttonPressed:(UIButton *)sender
{

    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES];
    [timer fire];
}
查看更多
成全新的幸福
3楼-- · 2020-02-06 18:27

All UI related things are done in the main thread. Forcing your runtime to sleep on the main thread will literally freeze your UI. Do it 180 times and you got one frustrated end-user.

查看更多
乱世女痞
4楼-- · 2020-02-06 18:34

You have to exit back to your runloop to allow the control to refresh. You should probably use an NSTimer that fires every second or so instead of a tight loop.

Although not really recommended, the following might also work if you call it right after setText:

[[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:nil];
查看更多
家丑人穷心不美
5楼-- · 2020-02-06 18:36

The sleep() does not allow the UI thread to update itself.

Here is a sample using GCD that closely matches you original code. Note: there are better ways to do this (see: dispatch_after()).

- (IBAction)buttonPressed:(UIButton *)sender {
    [label setText:[NSString stringWithFormat:@"%d", 0]];

    dispatch_queue_t queue = dispatch_queue_create("com.test.timmer.queue", 0);
    dispatch_async(queue, ^{
    for (int i = 1; i < 180; ++i) {
        sleep(1);
        dispatch_async(dispatch_get_main_queue(), ^{
            [label setText:[NSString stringWithFormat:@"%d", i]];
        });
    });
}
查看更多
登录 后发表回答