Search code examples
iosswiftwatchkittablerow

WatchKit - How to programmatically change background image of UITableViewCell using RowControllerAtIndex


I've been searching around trying to find out how to programmatically change the background image of a WatchKit TableViewCell based on the data of the array being passed to it.

I have two arrays passing data based on ["Time", "Act", "Location"] and I want Location to have a different background image based on the actual Location...

Is this possible? I was reading up on Delegates but they still elude me a little bit!

attempt so far:

Found out how to do it with WKInterfaceGroup See this code for answer

MAIN CLASS

private func timeTable(typesA: [String]) {
    var tempA: [String] = createTypesArray(typesA)
    ByTimeTable.setRowTypes(tempA)
    for var rowIndex = 0; rowIndex < typesA.count; rowIndex++ {
        switch tempA[rowIndex] {
        case "Time":
            let row = ByTimeTable.rowControllerAtIndex(rowIndex) as! TimeTableRowController
            row.timeLabel.setText(typesA[rowIndex])
        case "Act":
            let row = ByTimeTable.rowControllerAtIndex(rowIndex) as! ActTableRowController
            row.actLabel.setText(typesA[rowIndex])
        case "Location":
            let row = ByTimeTable.rowControllerAtIndex(rowIndex) as! LocationTableRowController
            if typesA[rowIndex] == "Silent Disco" {
                row.LocationGroup.setBackgroundImageNamed("disco")
            }
            else if typesA[rowIndex] == "Christmas Barn" {
                row.LocationGroup.setBackgroundImageNamed("xmas")
            }
            else if typesA[rowIndex] == "The Other Tent" {
                row.LocationGroup.setBackgroundImageNamed("other")
            }
            else if typesA[rowIndex] == "This Tent" {
                row.LocationGroup.setBackgroundImageNamed("this")
            }
            else if typesA[rowIndex] == "That Tent" {
                row.LocationGroup.setBackgroundImageNamed("that")
            }
            else if typesA[rowIndex] == "Which Stage" {
                row.LocationGroup.setBackgroundImageNamed("which")
            }
            else if typesA[rowIndex] == "What Stage" {
                row.LocationGroup.setBackgroundImageNamed("what")
            }
            row.locationLabel.setText(typesA[rowIndex])
        default:
            print("nope")
        }
    }
}

LocationTableRowController

import WatchKit

class LocationTableRowController: NSObject {

    @IBOutlet var locationLabel: WKInterfaceLabel!
    @IBOutlet weak var LocationGroup: WKInterfaceGroup!

}

Solution

  • Yes.

    First you set the number of rows based on your model, iterate through each record in the model, and determine what image to show.

    You will need to create a custom object which will be the class for each of your table rows. Here in this custom NSObject, you can create the property fields to display in the table. Then as we iterate, we assign these properties based on the model

    class myTableRow : NSObject{
        @IBOutlet weak var myText: WKInterfaceLabel!
        @IBOutlet weak var myImage: WKInterfaceImage!
    }
    

    and then somewhere in your controller you can do this.

    func loadTable(){
    
        myTable.setNumberOfRows(myModel.count, withRowType: "myTableRow")
    
        for(index, content) in myModel.enumerate(){
            let row = myTable.rowControllerAtIndex(index) as! myTableRow
            row.myLabel.setText("\(content.property1)")
    
           //do whatever logic you need to do to determine the correct image. You have access to your array here and its properties
          //...then
           row.myImage.setImage(content.imageToUse);    
    }
    

    update Since there are different templates of dynamic row, try setRowTypes

    It takes an array of strings, each of which corresponds to the name of a row controller defined in your storyboard file. The total number of items in this array is the number of rows to be created in the table.

    myTable.setRowTypes(["TimeTableRowController", "ActTableRowController", "ActTableRowController", "TimeTableRowController", "LocationTableRowController"])
    

    If you call this method I believe you no longer have to call the setNumberOfRows function.