执行另一个方法时(动态)更新标签文本

时间:2014-05-30 03:31:56

标签: ios objective-c uilabel

我是一名正在开发iphone应用程序的iOS开发人员。我有一个关于更新ViewController内容的简单问题,如果我能得到某人知道这个问题或有建议的解决方案的反馈,我将不胜感激。

我正在编写一种不断更新标签文本的方法(以及其他组件,例如UIImage“box1”和“box2”的背景颜色)。

问题 :对标签文本的更新(以及其他更改)仅在代码执行完毕时生效。所以我写了一个简单的无限循环,按如下方式执行:

-(void) stateTest{
    int i=0;
    for(;;){
       if (i==5) {
          self.stateLabel.text=@"Opened"; //stateLabel previously declared
          [self.box2 setBackgroundColor:[UIColor whiteColor]]; // box2 declared as UIImage
          [self.box1 setBackgroundColor:[UIColor purpleColor]];
        }
        if (i==10){
            self.stateLabel.text=@"Closed";
            [self.box2 setBackgroundColor:[UIColor redColor]];
            [self.box1 setBackgroundColor:[UIColor whiteColor]];
            break;
        }
        i++;
    }

}

并在viewDidLoad方法中:

- (void)viewDidLoad
{       
    [super viewDidLoad];
    self.stateLabel.text=@“View did Load";
    [self.box1 setBackgroundColor:[UIColorwhiteColor]];
    [self.box2 setBackgroundColor:[UIColorwhiteColor]];   
    [self stateTest];

}

我正在逐步完成代码(断点),这是我面临的问题:

  1. 当i == 5时,标签文本不会更新(与框的颜色相同)
  2. 当i == 10时,标签文本不会更新
  3. 执行代码完成后,将显示更新(标签文本和框颜色) stateLabel:“已关闭”, 方框2:红色背景颜色
  4. 我试过在stateTest方法结束时调用几个函数(在i ++之后)希望它将“ REFRESH ”视图,标签和/或UIImage的内容:< / p>

        [self.stateLabel setNeedsLayout];
        [self.stateLabel setNeedsDisplay];
        [self.box1 setNeedsDisplay];
        [self.box2 setNeedsDisplay];
        [self.view setNeedsDisplay];
    

    不幸的是,这些试验没有奏效。我还提出了一个输出标签文本的NSLog,它可以正常工作,如我所愿。但问题是在执行代码/方法期间动态更新视图控制器的内容。

    我非常感谢任何帮助,我对任何建议持开放态度

    理想情况,此代码与检测嘴巴状态的面部检测算法并行使用。有一个processImage方法,每帧处理图像。每次处理图像时都会调用[self stateTest];如果嘴巴张开→stateLabel.text = @“打开”......等等

    提前感谢您的贡献 干杯!

2 个答案:

答案 0 :(得分:2)

只有在运行循环完成后才会进行UI更新。通常我在后台线程中运行无限循环并在主线程中发布UI更新。这将负责运行循环。

以下代码仅供参考。

    -(void) viewDidLoad
    {
        [super viewDidLoad];
        self.subView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 30, 30)];
        self.subView.backgroundColor = [UIColor blueColor];

        [self.view addSubview:self.subView];



        dispatch_queue_t newQueue = dispatch_queue_create("newQueue", nil);
        dispatch_async(newQueue, ^{
            [self stateTest];
        });

    }

    -(void) stateTest{
        int i=0;
        for(;;){
            if (i==5) {
                [self performSelectorOnMainThread:@selector(purpleColor) withObject:self waitUntilDone:NO];

            }
            if (i==10){
                [self performSelectorOnMainThread:@selector(blueColor) withObject:self waitUntilDone:NO];
              //  break;
            }
            if (i==15){
                [self performSelectorOnMainThread:@selector(redColor) withObject:self waitUntilDone:NO];
                //break;
            }
            if (i==20){
                [self performSelectorOnMainThread:@selector(greenColor) withObject:self waitUntilDone:NO];
                break;
            }
            sleep(1);
            i++;
        }
    }

    -(void) purpleColor
    {
        [self.subView setBackgroundColor:[UIColor purpleColor]];
    }

    -(void) blueColor
    {
        [self.subView setBackgroundColor:[UIColor blueColor]];
    }

    -(void) redColor
    {
         [self.subView setBackgroundColor:[UIColor redColor]];
    }

    -(void) greenColor
    {
        [self.subView setBackgroundColor:[UIColor greenColor]];
    }

答案 1 :(得分:1)

在主线程(uithread)上运行无限循环并不是一个好主意。我可以建议您使用计时器或派遣事件吗?下面是一些可用于计时器的代码。我还要指出NSTimer无法重复使用。因此,如果您希望在失效后执行此操作,则需要重新创建计时器&amp;将它添加到runloop中。

// properties in your controller
@property (nonatomic) BOOL state;
@property (nonatomic, strong) NSTimer *timer;

// where to create it . timer interval is in seconds & use decimals if you want split seconds. 
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
}

// timer callback method
int count = 0;
- (void)onTimer:(NSNotification *)sender
{
    self.state = !self.state;

    if (self.state)
    {
        self.box1.backgroundColor = [UIColor redColor];
        self.box2.backgroundColor = [UIColor blueColor];
    }
    else
    {
        self.box1.backgroundColor = [UIColor yellowColor];
        self.box2.backgroundColor = [UIColor greenColor];
    }

    count++;

    if (count == 100)
    {
        [self.timer invalidate];
        [[[UIAlertView alloc] initWithTitle:@"timer done" message:@"timer finished" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show];
    }
}