Search code examples
swiftapple-watchwkinterfacetable

WKInterfaceTable, Row Controllers and Button actions in Swift


I'm having problems with a fairly basic task while experimenting with Apple Watch development in Swift. I recently received what appeared to be a perfect answer to the problem in Obj C but I can't seem to translate it.

I have one Interface controller that contains a table with multiple rows of the same row controller. Each row contains two buttons. When the button is tapped it's background image changes, but another function needs to be called in the interface controller class, and this function will need to access class-level variables in the interface controller class.

The Table is wired to the interface controller. And the buttons are wired to the row controller class. Here is my simplified Swift code. Thanks for having a look!

/// MY INTERFACE CLASS ///

class MainBoard: WKInterfaceController {

    @IBOutlet weak var TileGrid: WKInterfaceTable!

    let numRows = 3

    let imageNames =    ["img1","img2","img3"]

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)

        // Configure interface objects here.
        initBoard()
    }

    func initBoard() {                
        self.TileGrid.setNumberOfRows(self.numRows, withRowType: "Row")

        for var i = 0; i < numRows; i++ {

            let tmpImageA = UIImage(named: imageNames[0])
            let tmpImageB = UIImage(named: imageNames[1])

            let rowOfTiles = self.TileGrid.rowControllerAtIndex(i) as Row

            rowOfTiles.backImageA = tmpImageA
            rowOfTiles.backImageB = tmpImageB

        }        
    }

    func doSomething() {
        //this function needs to be called whenever a button is pressed
    }

}

///////MY ROW CONTROLLER CLASS ////////////////////////

class Row : NSObject {

    // At runtime these will be assigned based on the random game board creation
    var backImageA = UIImage(named: "default.png")
    var backImageB = UIImage(named: "default.png")

    @IBOutlet weak var TileA: WKInterfaceButton!
    @IBOutlet weak var TileB: WKInterfaceButton!

    @IBAction func TapTileA() {
        TileA.setBackgroundImage(backImageA)
        //NEED TO CALL FUNCTION DO SOMETHING IN INTERFACE CONTROLLER
    }

    @IBAction func TapTileB() {
        TileB.setBackgroundImage(backImageB)
        //NEED TO CALL FUNCTION DO SOMETHING IN INTERFACE CONTROLLER

    }

}

Solution

  • My best answer would be to create a delegate in your RowController class, then implement this delegate in your InterfaceController

    The delegate could have methods buttonOneClickHappened and buttonTwoClickHappened

    Then each RowController has the delegate as a property, and when you create the RowControllers call setDelegate: self where self is your InterfaceController

    Hope this helps.