David Robertson
David Robertson

Reputation: 1581

Multiple RowTypes in TableView - watchKit

It's rather easy to create a simple TableView with one row type. You just set

tableView.setNumberOfRows(yourArray.count, withRowType: "yourowtype")

and then add a for loop to fill up your uilabel or whatever you have with data from the array.

When it comes to multiple row types, it's not so clear. I'm aware you have to set

tableView.setRowTypes(yourRowTypesArray)

but i don't understand the rest.

In iOS you have a very clear and straightforward indexPath.row solution in the cellForRowAtIndexPath, where you can say - Okay, i want this array to fill those indexPaths, the other array should fill those e.t.c. with simple IF conditional.

In WatchKit, however, there is no such thing as indexPath.row and it's not clear to me how you can assign specific row numbers for a specific array ? And why should you remove setNumberOfRows (as i've seen in the examples all over the net) in a multiple row type solution?

I've browsed the net heavily regarding the issue and i haven't been able to find a decent workable solution. Just tricks and workarounds.

Thank you.

UPDATE: Adding codes

My arrays

var questionsList = [["[What is the color of?]"],["Which city is the capital of Great Britain", "additional info"],["Some question"]]
var answersList1 = [["Blue"],["London"],["some answer 1"]]
var answersList2 = [["Grey"],["Liverpool"],["some answer 2"]]

The loadTable function

private func loadTable(){
    tableView.setRowTypes(rowTypes)

    for i in 0 ..< questionsList[0].count {
        let rowController = tableView.rowControllerAtIndex(i) as! TableViewRowController
        rowController.lblQuestion.setText(questionsList[0][i])
    }

    let rowController1 = tableView.rowControllerAtIndex(answersList1[0].count) as! AnswerRowController1
    rowController1.button1.setTitle(answersList1[0][0])

    let rowController2 = tableView.rowControllerAtIndex(answersList2[0].count+1) as! AnswerRowController2
    rowController2.button2.setTitle(answersList2[0][0])
}

Upvotes: 0

Views: 349

Answers (1)

Sandeep
Sandeep

Reputation: 21154

I would rather suggest you to refine your model. It looks really difficult to understand. Refactor it into class or struct to make it easy to understand.

Here is my approach to refactor it a bit and create a sort of thing that you wanted,

let QuestionRowIdentifier = "QuestionRowIdentifier"
let AnswerRowIdentifier = "AnswerRowIdentifier"
let QuestionSeparatorRowIdentifier = "QuestionSeparatorIdentifier"


protocol QuestionAnswerRowTypes {
    var titleLabel: WKInterfaceLabel! { get set }
}

class QuestionRowController: NSObject, QuestionAnswerRowTypes {
    @IBOutlet var titleLabel: WKInterfaceLabel!
}

class AnswerRowController: NSObject, QuestionAnswerRowTypes {
    @IBOutlet var titleLabel: WKInterfaceLabel!
}

struct Question {
    let title: String
    let additionalInfo: String?
    let answers: [String]
}

let questions = [
   Question(title: "What is the color of?", additionalInfo: nil, answers: [
        "Blue",
        "Gray"
    ]),
    Question(title: "Which city is the capital of Great Britain?", additionalInfo: "additional info", answers: [
            "London",
            "Liverpool"
        ]),
    Question(title: "Some question?", additionalInfo: nil, answers: [
        "some answer 1",
        "some answer 2"
        ])
]

class InterfaceController: WKInterfaceController {

    @IBOutlet private var tableView: WKInterfaceTable!

    var names = ["Alexander", "Ferdinand", "Jack", "Samuel", "Thompson", "Tony"]

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

        let rowTypes = getRowTypes()

        tableView.setRowTypes(rowTypes)

        for i in 0 ..< rowTypes.count {
            if let rowController = tableView.rowControllerAtIndex(i) as? QuestionAnswerRowTypes {
                rowController.titleLabel.setText(textAtIndex(i)!)
            }
        }
    }

    func getRowTypes() -> [String] {
        return questions.flatMap { question in
            return [
                [QuestionRowIdentifier],
                Array(count: question.answers.count, repeatedValue: AnswerRowIdentifier),
                [QuestionSeparatorRowIdentifier]
                ].flatMap { $0 }
        }
    }

    func textAtIndex(index: Int) -> String? {
       let titles =  questions.flatMap { question in
            return
            [
                [Optional.Some(question.title)],
                question.answers.map(Optional.Some),
                [Optional.None],
            ]
        }.flatMap( { $0 })
        return titles[index]
    }
}

And here is the end result,

enter image description here

Upvotes: 2

Related Questions