【问题标题】:WKInterface button doesn't change titleWKInterface 按钮不改变标题
【发布时间】:2015-04-02 07:20:24
【问题描述】:

在我从通知中回拨后,我试图更改按钮的标题,但它根本没有响应。我检查了它不是零并检查了我正在分配的文本,一切都很好。我将属性类型设为strong 而不是weak,但没有成功。

- (void) setButtonTitleFromSelectedSearchResult:(NSNotification *)notif
{

    [self popController];

    self.sourceMapItem = [[notif userInfo] valueForKey:@"SelectedResult"];

    NSLog(@"The Selected Result is: %@", self.sourceMapItem.name);

    //Testing
    NSLog(@"%@", self.fromButton); // check it's not nil

    [self.fromButton setTitle:self.sourceMapItem.name];
}

【问题讨论】:

  • 只是为了澄清一下:该方法确实被调用了,您在控制台中看到两个NSLog 语句的输出?另外,popController 是做什么的?听起来它正在关闭当前的界面控制器,因此无论如何都不会更改按钮。
  • 是的,上面的代码被调用并且一切运行正常,给出了正确的 NSLogs 的结果,但是按钮并没有改变它的标题。 [self popController] 弹出一个控制器,该控制器之前在用户选择一个选项的地方出现,这是发布通知的位置,而当前控制器(self.fromButton 所在的位置)弹出该控制器,然后应该根据用户已选择。不用担心,即使它不存在,按钮也不会更改其标题。

标签: ios title watchkit wkinterfaceobject


【解决方案1】:

使用 WatchKit,如果用户界面元素当前不可见,则无法更新。因此,如果您“在顶部”呈现了另一个界面控制器,则在您关闭呈现的控制器之前,您无法更新任何呈现控制器的界面元素。此时,您可以安全地在其 willActivate 方法中更新呈现控制器。

SushiGrass 的块传递方法当然是一种有效的方法。然而,在我的测试中,我最终不得不管理多个块,并且许多后续块颠倒了之前排队的块已经完成的操作(例如,首先将标签的文本更改为“foo”,然后是“bar”,然后是“foo " 再次。虽然这可以工作,但它不是最佳的。

我建议任何正在开发 WatchKit 应用程序的人花点时间考虑一下他们希望如何考虑屏幕外(即当前不可见)的界面元素。 willActivate 是您的朋友,如果您要从一个控制器转移到另一个控制器,那么想出一种以该方法管理更新的方法是值得的。

不管怎样,我已经在 JBInterfaceController 子类中封装了很多这样的逻辑,它可以为你处理很多这样的事情。通过将其用作您自己的接口控制器的基类,您可以简单地在添加的didUpdateInterface 方法中更新您的元素。不幸的是,我还没有时间编写适当的文档,但是头文件和示例项目应该可以帮助您:https://github.com/mikeswanson/JBInterfaceController

【讨论】:

  • 能否请您提供有关“使用 WatchKit,如果用户界面元素当前不可见,则无法更新。”的文档?
【解决方案2】:

我正在使用最新的 XCode 6.3 及以下代码。 self.testBtn 与 Storyboard 及其 WKInterfaceButton 绑定

我还附上了影响结果的屏幕截图。

我在- (void)willActivate中设置初始文本

- (void)willActivate {
    [super willActivate];
    [self.testBtn setTitle:@"Test"];
    [self performSelector:@selector(justDelayed) withObject:nil afterDelay:5.0]
}

-(void)justDelayed
{
    [self.testBtn setTitle:@"Testing completed...!!"];
}

【讨论】:

  • 您可以尝试推动另一个界面控制器并形成该控制器发布通知,其中第一个控制器将通过关闭第二个控制器来响应它,然后像您在我的代码中看到的那样更改按钮文本?
【解决方案3】:

如果您为属性 fromButton 使用 IBOutlet,请确保它已连接到情节提要上的 WKInteface,如下所示:

【讨论】:

  • 它已连接,并在第三次尝试之前响应更改标题两次,但没有任何反应。
  • 不幸的是,我无法理解问题出在哪里,您必须更具体地使用代码。第三次收到通知?你确定[self.fromButton setTitle:self.sourceMapItem.name];是在主线程中执行的吗?
  • 我的意思是按钮在其他地方正确更改其标题,而不是来自对 NSNotification 的响应(上面的代码)。我使用if ([NSThread isMainThread]) { NSLog(@"is main thread"); } 检查主线程,它实际上是主线程。我尝试在dispatch_async(dispatch_get_main_queue(), ^{ [self.fromButton setTitle:self.sourceMapItem.name]; }); 中更改按钮的标题,但也没有成功。
  • 使用 WatchKit,如果用户界面元素当前不可见,则无法更新。如果您将另一个界面“推到顶部”,则必须考虑到这一点。然后,当基接口控制器的 willActivate 被调用时,您就可以执行更新了。
  • 很高兴听到您解决了问题!我已将我的评论提升为答案并进行了详细说明,以使其更有用。
【解决方案4】:

我通过创建一个具有() -> (Void) 类型块属性的模型对象解决了这类问题(在 swift 中)。我创建模型对象,在块中设置我希望推送WKInterfaceController 在完成时执行的操作,最后将上下文中的模型对象传递给推送WKInterfaceController。推送的WKInterfaceController 持有对模型对象的引用作为属性,并在它完成需要做的任何事情时以及在func popController() 之后调用它的完成块。

这对我来说适用于您所描述的模式以及删除详细控制器删除、网络调用、位置获取和其他任务的行。

你可以在这里看到我在说什么:https://gist.github.com/jacobvanorder/9bf5ada8a7ce93317170

【讨论】:

  • 这听起来很有趣,但你能把代码贴出来让我试试吗?最好是客观-C。谢谢。
  • 我尝试了一种类似 SushiGrass 的技术,它对于简单的更新效果很好。然而,更复杂的更新需要多个块,这变得很麻烦。我最终编写了一个 WKInterfaceController 子类,它推迟屏幕更新,直到视图真正可见。你可以在我的 GitHub 项目中看到一个示例:github.com/mikeswanson/JBInterfaceController
  • @mikeswanson,这非常可靠!谢谢分享。这里有很多很好的小信息。
  • @SushiGrassJacob 我无法打开要点链接。只是一个空白的浏览器页面。我应该做一些特别的事情来打开它吗?
  • @Ali,现在就试试吧。对不起!
猜你喜欢
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
相关资源
最近更新 更多