web-dev-qa-db-ja.com

UITableViewCellにジェスチャーを追加する方法は?

UITableView内のすべてのセルにタップジェスチャを追加して、その中のコンテンツを編集します。ジェスチャーを追加する2つの方法は、コードを使用する方法とストーリーボードを使用する方法です。両方試してみたが失敗した。

ストーリーボードのドラッグアンドドロップでeveryテーブルのセルにジェスチャーを追加できますか?最初のセルにジェスチャを追加するだけのようです。コードにジェスチャーを追加して、次のようなものを書きました。

addGestureRecognizer(UITapGestureRecognizer(target: self,action:#selector(MyTableViewCell.tapEdit(_:))))

または

addGestureRecognizer(UITapGestureRecognizer(target: self, action:"tapEdit:"))

両方とも機能します。しかし、UITableViewControllerがこのジェスチャーを処理できるようにしたいのは、それがデータソースで何かをするからです。ターゲットとアクションを作成するにはどうすればよいですか?

編集:

addGestureRecognizer(UITapGestureRecognizer(target: MasterTableViewController.self, action:#selector(MasterTableViewController.newTapEdit(_:)))

それは、クラス0x106e674e0に送信された認識されないセレクターというエラーを引き起こします...

10
Fate Riddle

UITableViewCellにジェスチャーを追加するには、次の手順に従います。

まず、ジェスチャー認識機能をUITableViewに追加します

tapGesture = UITapGestureRecognizer(target: self, action: #selector(tableViewController.tapEdit(_:)))
tableView.addGestureRecognizer(tapGesture!)
tapGesture!.delegate = self

次に、セレクターを定義します。使用する recognizer.locationInViewをタップして、tableViewでタップしたセルを見つけます。また、ユーザーがタップしたセルのindexPathであるtapIndexPathを使用して、dataSourceのデータにアクセスできます。

func tapEdit(recognizer: UITapGestureRecognizer)  {
    if recognizer.state == UIGestureRecognizerState.Ended {
        let tapLocation = recognizer.locationInView(self.tableView)
        if let tapIndexPath = self.tableView.indexPathForRowAtPoint(tapLocation) {
            if let tappedCell = self.tableView.cellForRowAtIndexPath(tapIndexPath) as? MyTableViewCell {
                //do what you want to cell here

            }
        }
    }
}

TableViewセルにジェスチャーを直接追加し、viewControllerのデータソースにアクセスすることができます。デリゲートを設定する必要があります。

カスタムセル内:

import UIKit


class MyTableViewCell: UITableViewCell {

    var delegate: myTableDelegate?

    override func awakeFromNib() {
        super.awakeFromNib()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(MyTableViewCell.tapEdit(_:)))
        addGestureRecognizer(tapGesture)
        //tapGesture.delegate = ViewController()

    }

    func tapEdit(sender: UITapGestureRecognizer) {
        delegate?.myTableDelegate()
    }

}

protocol myTableDelegate {
    func myTableDelegate() 
}

あなたのviewControllerで:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate, myTableDelegate {

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self
        // Do any additional setup after loading the view, typically from a nib.
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 35
    }

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

        cell?.delegate = self

        return cell!
    }

    func myTableDelegate() {
        print("tapped")
        //modify your datasource here
    }

}

ただし、このメソッドは問題を引き起こす可能性があります。 IGestureRecognizerおよびUITableViewCellの問題 を参照してください。この場合、スワイプジェスチャーが成功すると、何らかの理由でセレクターが2回呼び出されます。直接的な証拠はまだ見つかっていないので、2番目の方法が悪いとは言えませんが、Googleで検索した後、最初の方法が標準的な方法のようです。

38
billphilip22

あなたがしていることを達成するためにジェスチャー認識を追加する必要はありません。

  • UITableViewDelegateメソッドを使用するtableView:didSelectRowAtIndexPath:タップされた行を検出し(これはまさにtapGestureが行うことです)、その後、希望する処理を行います。
  • セルを選択したときに灰色の表示が気に入らない場合は、tableView:didEndDisplayingCell:forRowAtIndexPath:セルを返す直前:
    cell?.selectionStyle = .None
8
Rohan Sanap

AwakeFromNibメソッドでジェスチャを追加する方がはるかに簡単で、うまく機能します。

class TestCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()

        let panGesture = UIPanGestureRecognizer(target: self,
                                            action: #selector(gestureAction))
        addGestureRecognizer(panGesture)
    }

    @objc func gestureAction() {
        print("gesture action")
    }
}
2
LembergSun