swiftwatchkitapple-watchwkinterfacecontroller

How to dismiss WKInterfaceController from another controller?


I am creating my first WatchOS app as a companion to an iOS app.

The Watch App needs to be able to display a bingo ball whose number is sent from the phone. Since I can't overlay images with WatchOS, I've created 6 WKInterfaceControllers. One is the 'main' controller, and the other 5 each have a unique background image which is a bingo ball of the correct color (Blue, Red, Gray, Green and Yellow) and then I overlay a label with the ball letter and number (ie B14). I couldn't find a way to dynamically manipulate the background image of a single WKInterfaceController - but if there is a way to do so - I'd greatly appreciate a tip on how to do this and my other problem wouldn't exist.

Currently, I'm using WatchConnectivity from within the Main controller to receive updates from the phone. When the phone sends a number, the code determines the color it needs to be and then the following code presents the WKInterfaceController with the correct color background:

let nextName = "\(ballColor)Controller"
DispatchQueue.main.async {
    self.presentController(withName: nextName, context: message)
    WKInterfaceDevice().play(.click)
}

The problem I'm having is that once I activate the first color controller, I can't activate a different color controller without dismissing the currently active one.

So - how can I do this? I think I just need a way to hold a reference to the active controller so I can dismiss it before activating the one for the next ball - but I can't figure out how to do that.

I would appreciate it if someone could help point me in the right direction here…

Thanks in advance


Solution

  • I don't know if my original question has an answer. From what I can see, it doesn't seem possible to store a reference to the active WKInterfaceController and interact with it from another controller - but I did find a way to address my underlying problem. I'm posting my findings in case others get stuck in the same way I was.

    I was under the mistaken impression that the only way to overlay text on a graphic in WatchKit was to set the WKInterfaceController background to an image and then place a label on top of it - but the background image property of the WKInterface Controller is unavailable to set programmatically so I created a separate instance of WKInterfaceController for each different background image I wanted to use. But as I expected, there was another, better way.

    The "group" object also has a background image property and it IS possible to set this programmatically.

    I deleted my 5 separate interface controllers and replaced them with 1 interface controller containing a group, then I set the background image of the group programmatically from session:didReceiveMessage to be the appropriate image for the latest data received from the phone.

    The only complexity that still remained was that I still couldn't manipulate anything on this WKInterfaceController from my main WKInterfaceController which was also serving as my WCSessionDelegate. The only way I found to deal with this was to deactivate the WCsession by setting WCSession.default.delegate to nil from the session:didReceiveMessage function immediately before presenting the second controller, and then activating it again in awake:withContext within the second controller which also required that I import WatchConnectivity and conform to WCSessionDelegate.