Search code examples
iosswiftwatchkit

Pushing A New WatchKit Controller Immediately After Popping Another Always Fails


OK. It's easy enough to do this in classic iOS, but WatchKit doesn't give any blocks/closures, and there isn't a choice between with/without animation.

I have a root controller that has a list of options. Touching one of the options (on either the watch or the phone) will close any currently open controller (popToRootController), then immediately, push a new one.

More or less, like so:

self.popToRootController()
self.pushController(withName: "IKANHAZCHEEZEBURGR", context: nil)

The problem is that there isn't enough time between the calls, and there's no lambda for me to execute a semaphore or push the controller.

If I step through with the debugger, it happens, no problem. If I just hit "run," it no work. This is what is known as a "heisenbug".

I guess I could do a one-shot timer, but that seems to be such a hideous hack that it may actually cause a disruption of The Force.

Any better ideas? What am I missing?

I know there's a TON of answers for iOS. They don't do me a whole lot of good, here.


Solution

  • Well, I succumbed to The Dark Side, and did the timer hack. It works. I need to give it around 0.4 seconds per open controller.

    Here's an approximation of what I did:

    self.popToRootController()
    let _ = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.timerCallback(_:)), userInfo: nil, repeats: false)
    
    func timerCallback(_ timer: Timer) {
        if let timerIndex = timer.userInfo as? Int {
            if 0 <= timerIndex {
                DispatchQueue.main.async {self.pushController(withName: "IKANHAZCHEEZEBURGR", context: nil)}
            }
        }
    }
    

    UPDATE: I do want to mention that, even though this "solves" my issue, the issue that this issue is even an issue is an issue. My design was bad, and I am redesigning the basic navigation. I'll be using a page-based approach, instead of this hierarchical design.

    On general principle, if I need to hack to make it work, I'm usually better off doing it a different way.