我的WatchKit App故事板上有一个WKInterfaceLabel
。每隔30秒,WatchKit应用程序将向父iPhone应用程序发送请求以获取字符串。收到字符串后,我将字符串设置为WKInterfaceLabel
的文本。代码如下所示:
NSDictionary *getTokenRequest = @{@"request":@"getToken"};
[InterfaceController openParentApplication:getTokenRequest reply:^(NSDictionary *replyInfo, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
token = replyInfo[@"token"];
NSLog(@"token=%@", token); // I am getting the correct token
// But the following line doesn't update label text
[self refreshToken];
}
}];
- (void)refreshToken {
if ([token length] != 0) {
[self.codeLabel setText:token];
}
}
当应用启动或恢复时,标签将显示从父应用返回的正确字符串。这是因为在refreshToken
中调用willActivate
。什么不起作用的是当我每隔30秒从父应用程序请求数据时,我也在请求的回调中调用refreshToken
,如上面的代码所示,即使我得到正确的字符串({{1来自手机应用程序并致电token
。它是相同的方法调用:在[self.codeLabel setText:token]
内调用时,willActivate
更新标签,但在请求的回调方法中调用时,标签文本UI不会更新。
此问题仅在设备上发生。在模拟器上运行时,标签文本按预期每30秒更新一次。
当我开发iPhone应用程序时,我曾遇到类似的问题,并通过在主线程上调用setText
方法解决了这个问题:
setText
可悲的是,Apple Watch的不工作方式相同。
我在这里也找到了一个类似的线程:can setText for WKInterfaceLabel in init method but not in didselectrow method但它没有提供一个好的解决方案。
任何建议/想法都表示赞赏。提前谢谢!
答案 0 :(得分:1)
最后,这对我有用:
- (void)refreshToken {
dispatch_async(dispatch_get_main_queue(), ^{
[self.codeLabel setText:token];
});
}
感谢此帖http://iosdevelopmentjournal.com/blog/2013/01/16/forcing-things-to-run-on-the-main-thread/。
简而言之,当你告诉它时UI没有更新时,它可能没有安排在主线程上运行。
如我的问题所示,我已经怀疑线程问题,并试图使用performSelectorOnMainThread
,但它没有用。对于那些好奇的人,这是performSelectorOnMainThread
和dispatch_async
之间的区别:Whats the difference between performSelectorOnMainThread and dispatch_async on main queue?
答案 1 :(得分:0)
失败的原因是当您尝试更新UI时,控制器未处于活动状态。
更新UI的正确时间应该是“willActivate”方法。
另一个解决方案是在更新UI之前添加一些延迟(performSelector:@selector(UPDATE_UI)withObject:NULL afterDelay:1]。
答案 2 :(得分:0)
失败的原因是当您尝试更新UI时,控制器未处于活动状态
这是我案例中的问题。我在我的父控制器上保留了一个引用,并尝试在那里进行更改(在当前控制器的willDeactivate()中)。这适用于模拟器,但不适用于设备。我需要在didDeactivate()中进行更改,以便父控制器已经处于活动状态:
override func didDeactivate()
{
//Update UI of parent Controller here
self.parentController.updateUI()
}
也许对某人有所帮助。