技術はメシのタネ

底辺プログラマで技術の向上を目指しているけれどやりたい事が無くて困っている

【今度こそ】カスタムセルに設置したUISwitchのindexPathを取得する

恥ずかしい恥ずかしい恥ずかしい!
昨日書いたarticleが「カスタムセル uiswitch superview」でググると一番最初に表示されますが、解決方法が間違っています……orz

techmeganeyamada.hatenadiary.com

ちょっと言葉を変えてきちんと検索すると、正しい答えをグーグル先生は教えてくれました。

func handleTouchSwitch(sender: UISwitch) {
    let point: CGPoint = sender.layer.position
    let indexPath = self.tableView.indexPathForRowAtPoint(point)
    let object = objects[indexPath!.row] as! NSDate
    println(object)
}

上記のやり方では、何番目のセルを選択したか、わかりません。
取得できるCGPointは何番目のセルを選択しても同じ座標を返してきます。

objc-lovers.com

↑ 参考サイト1

昨日のarticleではUISwitchsuperviewを用いた方式だと上手くいかなかった、と書きました。
参考サイト1にも示されていますが、どうやらiOSのバージョンによってセルの階層構造が変化したことが原因だったようです。
要するに、最初に参考にしたサイトが古いiOSについて書かれたものだったようですね。
参考サイト1にはiOS7での階層構造が示されていますが、いつまたこれが変更になるか、わかりません。
次のiOS9でまた変わってしまうかも。

となると、手動でカスタムセルのクラスにたどり着く方法はあまり賢明とは言えません。

blog.livedoor.jp

↑ 参考サイト2

ああ、先人は偉大ですねえ。
参考サイト2ほど高度な解決策を今回は求めていないので、必要な箇所だけ採用させて頂きます。

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    let object = objects[indexPath.row] as! NSDate
    cell.textLabel!.text = object.description
    cell.customSwitch.addTarget(self, action: "hundleSwitch:", forControlEvents: UIControlEvents.ValueChanged)
    return cell
}
func hundleSwitch(sender: UISwitch) {
    var hoge = sender.superview
    while(hoge!.isKindOfClass(CustomCell) == false) {
        hoge = hoge!.superview
    }
    let cell = hoge as! CustomCell
    // touchIndexは選択したセルが何番目かを記録しておくプロパティ
    touchIndex = self.tableView.indexPathForCell(cell)
}

こうしておけば、セルの階層構造がiOSのバージョンアップで変化があったとしても対応できます。

ああ、赤っ恥……。