Apple Watch:WKInterfaceLabel不会在设备上更新,但在模拟器上会很好

时间:2015-06-08 23:28:26

标签: ios objective-c watchkit apple-watch

我的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但它没有提供一个好的解决方案。

任何建议/想法都表示赞赏。提前谢谢!

3 个答案:

答案 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,但它没有用。对于那些好奇的人,这是performSelectorOnMainThreaddispatch_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()
}

也许对某人有所帮助。