UITableViewCell内の画像をタップした時に行番号を取得する方法をいくつか紹介します。
準備
-
UItableViewCell
にUIImageView
を配置します。 -
配置した
UIImageView
からコードに対してoutletを定義します。このページでは
icon
という名前にします。@IBOutlet weak var icon: UIImageView!
-
上記
UIImageView
のuser interactionを有効にしておきます。(コードで実装する場合は省略)
パターン1. UITableViewControllerの中で実装
UITableViewControllerの中で素直に取得します。
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! SampleTableViewCell
if cell.icon.gestureRecognizers?.count == 0 { //重複登録チェック(※)
//gestureを設定
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("tapIcon:"))
cell.icon.addGestureRecognizer(tapGesture)
cell.icon.userInteractionEnabled = true
}
return cell
}
※ 重複登録を防ぐためにgestureRecognizers
でUIImageView
に登録されたジェスチャーを取得しています。ここでは簡略のためにgestureRecognizers?.count
でUIImageView
に登録されたジェスチャーの個数だけをチェックしていますが、複数タイプのジェスチャーを登録する場合など厳密にチェックしたい場合はgestureRecognizers
の中を見て判定した方が良いです。
func tapIcon(gestureRecognizer: UITapGestureRecognizer) {
let tappedLocation = gestureRecognizer.locationInView(tableView)
let tappedIndexPath = tableView.indexPathForRowAtPoint(tappedLocation)
let tappedRow = tappedIndexPath?.row
print(tappedRow)
}
※ mm36さんにアドバイスもらいました。ありがとうございます。
パターン2. UITableViewCellの中で実装
UITableViewCellから自分のいるUITableViewControllerを取得します。
override func awakeFromNib() {
super.awakeFromNib()
// 略
//gestureを設定
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("tapIcon:"))
tapGesture.delegate = self;
icon.addGestureRecognizer(tapGesture)
}
func tapIcon(sender: UITapGestureRecognizer) {
let tableView = superview?.superview as! UITableView //UITableViewを取得
let tappedIndexPath = tableView.indexPathForCell(self) //自分のIndexPathを取得
let tappedRow = tappedIndexPath?.row //IndexPathから行を取得
debugPrint(tappedRow)
}
パターン3. レスポンダチェーンを使ってUIImageViewからUITableViewControllerにイベントを送る
- UITableViewCell内のUIImageViewにタップのジェスチャーを設定します。
- タップされたらレスポンダチェーンに
sendAction
して、UITableViewController
に来た時点で受け取って任意の処理を行います。
@tomohisaota さんからアドバイスいただきました。ありがとうございます。
UITableViewCell
内の実装
override func awakeFromNib() {
super.awakeFromNib()
略
//ジェスチャーの登録
icon.userInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("iconTapped:"))
icon.addGestureRecognizer(tapGesture)
}
// ジェスチャーのアクション
@IBAction func iconTapped(sender: AnyObject) {
//レスポンダチェーンにアクションを送信
UIApplication.sharedApplication().sendAction("iconTappedAction:", to: nil, from: icon, forEvent: nil)
}
UITableViewController
内の実装
func iconTappedAction(sender:AnyObject?) {
guard let gestures = sender?.gestureRecognizers! else { return }
for gesture in gestures {
if let gesture = gesture as? UITapGestureRecognizer {
let tappedLocation = gesture.locationInView(tableView)
let tappedIndexPath = tableView.indexPathForRowAtPoint(tappedLocation)
let tappedRow = tappedIndexPath?.row
debugPrint(tappedRow)
}
}
}