37
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UITableViewCell内の画像がタップされた時にUITableViewの行番号を取得するいくつかの方法

Last updated at Posted at 2016-01-09

UITableViewCell内の画像をタップした時に行番号を取得する方法をいくつか紹介します。

準備

  1. UItableViewCellUIImageViewを配置します。

  2. 配置したUIImageViewからコードに対してoutletを定義します。

    このページではiconという名前にします。

    @IBOutlet weak var icon: UIImageView!
    
  3. 上記UIImageViewのuser interactionを有効にしておきます。(コードで実装する場合は省略)

    UIImageにTapGestureを指定したのに、反応してくれなくて困ったとき

パターン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
}

※ 重複登録を防ぐためにgestureRecognizersUIImageViewに登録されたジェスチャーを取得しています。ここでは簡略のためにgestureRecognizers?.countUIImageViewに登録されたジェスチャーの個数だけをチェックしていますが、複数タイプのジェスチャーを登録する場合など厳密にチェックしたい場合は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にイベントを送る

  1. UITableViewCell内のUIImageViewにタップのジェスチャーを設定します。
  2. タップされたらレスポンダチェーンに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)
        }
    }
}
37
38
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?