WKInterfacePicker setSelectedItemIndex causes hang

Wondering if anyone else has seen this? I filed a bug, but now I'm just looking for a workaround.


Here's the set up:


Xcode 7.0 beta 6 (7A192o) running a simple WatchKit 2.0 app

Simulator or real AppleWatch

Swift


1. Create a simple Watch OS 2.0 app

2. Create an initial InterfaceController with 3 controls: 1 WKInterfacePicker and 2 WKButtons

3. Create a second InterfaceController with an identifier of "Next"

4. In awakeWithContext load the picker with 50 strings (e.g. "1" to "50")

5. Make sure picker has an associated action: @IBAction func pickerSelectedItemChanged(value: Int) function (no code is required within function)

6. In first button, call self.myPicker.setSelectedItemIndex(42)

7. In second button, call self.pushControllerWithName("Next", context: nil)


Now, run the watch app and do the following:


1. Tap the button that calls setSelectedItemIndex

2. Then QUICKLY, tap the second button that calls self.pushControllerWithName("Next", context: nil)


Observed result:


When the "Next" InterfaceController loads, it first appears with a small network activity indicator, then loads a large activity indicator, and disables all controls in the "Next" interface controller.

Replies

Hi, I'm also facing the same issue in an quite similar case.

My app has three wkinterfaces in page view mode. If a call to setselecteditemindex() is done in an interface that is not displayed (i.e. in viewWillActivate())some sort of freeze happens to the UI, and the app becomes unstable and irresponsive, specially when presented an MediaPlayerControllerWithUrl().


The only way I have found to workaround the problem is to move the call to an stage where the selection is visible to the user interface (in my case after viewDidAppear). Not the nicest way, but works.


As a workaround, I'd suggest you to force a little delay after setSelectedItemIndex. Yes, it's a hack, but I'm pretty sure it will work. You can find the code to simulate a delay in the PotLoc example:


/*
        Simulates fading out animation by setting the alpha of the given label to
        progressively smaller numbers.
    */
    func simulateFadeOut(label: WKInterfaceLabel) {
        let mainQueue = dispatch_get_main_queue()
   
        for index in 1...10 {
            let time = dispatch_time(DISPATCH_TIME_NOW, Int64(Double(index) / 10.0 * Double(NSEC_PER_SEC)))
            dispatch_after(time, mainQueue) {
                //Actually do nothing

            }
        }
    }


(swift code, easy to adapt to Obj-c)

Hope this helps...

Yep, I resorted to a 1/2 second artificial delay; appears to work for most cases. Did not animate, but I'll think about that. Thanks