web-dev-qa-db-ja.com

SwiftのUITableViewCellサブクラス内からIndexPathを取得します

カスタムUITableViewCellサブクラスとそれに関連付けられたxibがあります。このセルにはUILabelUIButtonがあり、ボタンのアクション内のタッチアップをサブクラスに配線しました。

必要なのは、セル内のボタンがタップされたときに、そのボタンを持つセルのインデックスパスを取得することです。また、デリゲートなどを介してView Controllerに送信することもできます。

私はUITableViewCellサブクラスの中にいるので、セルサブクラスの中からtableviewへの参照がないため、 this のようなソリューションを使用できません。さらなる調査の結果、 別の 解決策を見つけ、Swiftのように実装しました。

import UIKit

class ContactCell: UITableViewCell {

    @IBOutlet weak var nameLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        selectionStyle = .None
    }

    @IBAction func callButtonPressed(sender: UIButton) {
        let indexPath = (self.superview as UITableView).indexPathForCell(self)
        println("indexPath?.row")
    }

}

しかし、ボタンをタップすると、Swift dynamic cast failedというエラーメッセージが表示されてクラッシュします。

私のコードのどこに問題があるのでしょうか?

または、他の方法で目的の結果を達成できるようにする他の提案を受け入れています。

ありがとうございました。

20
Isuru

デリゲートが必要なようです:

Swiftのデリゲート?

次に、セル自体をパラメータとしてデリゲートに渡すだけで、tableView.indexPathForCell(cellFromDelegateMethod)を簡単に実行できます

22
ullstrm

UIButton.Typeには実際にはメンバースーパービューはありませんが、送信者にはスーパービューがあります

var cell: UITableViewCell = sender.superview.superview as UITableViewCell

ボタンの「タグ」も使用できます。テーブルデリゲートuのcellForRowAtメソッド内で、ボタンにIndexpath.rowのタグを付けることができます。ここに私が言った例があります。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// get ur cell nib .As it has a button
cell.startOrConntinuBtn.addTarget(self, action: #selector(sumbitOrContinue), for: .touchUpInside) 

cell.startOrConntinuBtn.tag = indexPath.row }

そしてタッチメソッド「sumbitOrContinue」で-

 func sumbitOrContinue(sender: UIButton!) { 
let tag = sender.tag
// do what you want to do like this example

let detail = self.detailList[tag]
let vc  = self.storyboard?.instantiateViewController(withIdentifier: "mockExamInt") as! MockWindowVc
vc.detailId = detail.id
self.navigationController?.pushViewController(vc, animated: true)}
2
Sibasish