我是一名正在开发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];
}
我正在逐步完成代码(断点),这是我面临的问题:
我试过在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 = @“打开”......等等
提前感谢您的贡献 干杯!
答案 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];
}
}