Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WKInterface button doesn't change title

I'm trying to change the title of a button after I call back from a notification but it doesn't respond at all. I checked it's not nil and checked the text Im' assigning and all is good. I made the property type strong instead of weak but no success.

- (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];
}
like image 308
Ali Avatar asked Apr 02 '15 07:04

Ali


4 Answers

With WatchKit, if a user interface element isn't currently visible, it cannot be updated. So, if you've presented another interface controller "on top", you can't update any of the presenting controller's interface elements until you've dismissed the presented controller. At that point, you can safely update the presenting controller in its willActivate method.

SushiGrass' method of passing blocks is certainly one valid approach. In my testing, however, I ended up having to manage multiple blocks, and many of the subsequent blocks reversed what earlier queued blocks had accomplished (for example, first changing a label's text to "foo", then "bar", then "foo" again. While this can work, it isn't optimal.

I'd suggest that anyone who is working on a WatchKit app takes a moment to consider how they want to account for off-screen (i.e. not-currently-visible) interface elements. willActivate is your friend, and coming up with a way to manage updates in that method is worthwhile if you're moving from controller to controller.

For what it's worth, I've encapsulated a lot of this logic in a JBInterfaceController subclass that handles a lot of this for you. By using this as a base class for your own interface controller, you can simply update your elements in the added didUpdateInterface method. Unfortunately, I haven't yet had the time to write proper documentation, but the header files and sample project should get you going: https://github.com/mikeswanson/JBInterfaceController

like image 82
Mike Swanson Avatar answered Oct 21 '22 05:10

Mike Swanson


I'm using latest XCode 6.3 and below code working with me. self.testBtn is bind with Storyboard and its WKInterfaceButton

I also have attached screenshot with affected result.

I'm setting initial text in - (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...!!"];
}

enter image description here

enter image description here

like image 20
Ashvin A Avatar answered Oct 21 '22 04:10

Ashvin A


If you're using an IBOutlet for the property fromButton be sure that is connected to WKInteface on the storyboard, like below:

IBOutlet

like image 2
Andr3a88 Avatar answered Oct 21 '22 05:10

Andr3a88


I solved this kind of issue by creating a model object that has a property that is a block of type () -> (Void) (in swift). I create the model object, set the action in the block that I'd like the pushing WKInterfaceController to do on completion, and finally pass that model object in the context to the pushed WKInterfaceController. The pushed WKInterfaceController holds a reference to the model object as a property and calls it's completion block when it's done with whatever it needs to do and after func popController().

This worked for me for patterns like what you are describing along with removing rows on detail controller deletion, network calls, location fetches and other tasks.

You can see what I'm talking about here: https://gist.github.com/jacobvanorder/9bf5ada8a7ce93317170

like image 2
SushiGrass Jacob Avatar answered Oct 21 '22 04:10

SushiGrass Jacob