我正在使用CMMotionManager
来检索加速度计数据。问题是加速度计数据会定期打印,实例变量会在视图中更改,但视图不会重新绘制。我已经检查过hv
不是零并且所有内容都被挂钩了。在块中调用setNeedsDisplay是否有问题?
-(void) viewDidAppear:(BOOL) animated
{
[super viewDidAppear: animated];
[motionManager startAccelerometerUpdatesToQueue:motionQueue withHandler:
^(CMAccelerometerData *accelerometerData, NSError *error)
{
NSLog(@"%@",accelerometerData);
HypnosisView *hv = (HypnosisView *) [self view];
hv.xShift = 10.0 * accelerometerData.acceleration.x;
hv.yShift = -10.0 * accelerometerData.acceleration.y;
[hv setNeedsDisplay];
}];
}
答案 0 :(得分:12)
这是因为你在与主线程不同的线程上调用UI方法。
将此添加到您的块中:
dispatch_async(dispatch_get_main_queue(), ^{
[hv setNeedsDisplay];
});
请记住,必须从主线程调用任何处理用户界面元素的方法。
答案 1 :(得分:4)
我在其他块中也做了同样的事情并且它确实有效,但不是你在这里使用的回调。也许块没有在主线程上执行?您可以通过以下方式检查:
NSLog(@"Main thread? %d", [NSThread isMainThread]);
如果不是,您可以强制setNeedsDisplay
在主线程上运行。
答案 2 :(得分:0)
只想测试@ cocoahero的答案。我试图在非主线程中调用setTitle
来获取UIButton。标题确实改变了。我尝试使用Xcode 5.0.1定位iOS 5.1和7.0。我也从非主线程调用了setNeedsDisplay
,它也起作用了。
[NSThread isMainThread]
是我如何确保我的电话不是来自主线程的。我不确定从非主线程调用是导致问题的原因,但至少还有其他可能性。您可以查看my answer以了解其他问题。