【Swift】UITableViewCellでスワイプしているか、していないかを取得する方法【Xcode11/iOS13】

こういう人に向けて発信しています。
・現在スワイプされているかを判定したい人
・スワイプが終了したタイミングを検知したい人
・Swift中級者

Swipeについて知識

extension ViewController: UITableViewDelegate {
   func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?{
       isSwiping = true
       //スワイプされる都度、最新のスワイプされたセルのIndexPathを保存しに行く。
       swipeCellIndexPath = indexPath;
       
       // スワイプ時OKボタンのみを表示する。
       let okButton: UITableViewRowAction = UITableViewRowAction(style: .normal, title: "OK!") { (action, index) -> Void in
           tableView.isEditing = false
           print("tapped_OkButton")
       }
       okButton.backgroundColor = UIColor.blue
       return [okButton]
   }
}

上記をみていただけると分かりますが、
・スワイプ開始時
・スワイプしてボタン押下時
のタイミングは取得できますが、

スワイプを開始して何もせず閉じた場合などは検知できません。

今現在スワイプしているかを下記のような方法で実現しました。


import UIKit

class ViewController: UIViewController{
   @IBOutlet weak var tableView: UITableView!
   var swipeCellIndexPath : IndexPath = []
   
   override func viewDidLoad() {
       super.viewDidLoad()
       self.tableView.dataSource = self;
       self.tableView.delegate = self;
   }
   
   //非同期通信の結果受け取った後、画面更新したい際などにこのメソッド呼んであげる
   /*
   func swipeEndNotification() -> Void {
       if checkSwiping(){
           //スワイプ中なら行いたい処理
           DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
               // 1.0秒後に再度本メソッドを実行して再度終了しているかを確認する処理
               self.swipeEndNotification()
           }
       }else{
           //スワイプしていない時に行いたい時
           tableView.reloadData()
       }
   }
    */
   
   //現在スワイプ中かを確認するメソッド
   func checkSwiping() -> Bool {
       let swipeCell = tableView(self.tableView, cellForRowAt: swipeCellIndexPath)
       let cellRect = swipeCell.frame
       return cellRect.origin.x != 0
   }
   
}


extension ViewController: UITableViewDataSource {
   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "Cell")
       // セルに表示する値を設定する
       cell.textLabel!.text = indexPath.row.description
       return cell
   }
   
   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return 10;
   }
}

extension ViewController: UITableViewDelegate {
   func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?{
       //スワイプされる都度、最新のスワイプされたセルのIndexPathを保存しに行く。
       swipeCellIndexPath = indexPath;
       
       // スワイプ時OKボタンのみを表示する。
       let okButton: UITableViewRowAction = UITableViewRowAction(style: .normal, title: "OK!") { (action, index) -> Void in
           tableView.isEditing = false
           print("tapped_OkButton")
       }
       okButton.backgroundColor = UIColor.blue
       return [okButton]
   }
}

解説

ロジックとしてはシンプルでセルの座標xが0かどうかでSwipeかどうか
判定しております。

スワイプ時に右にも左にもスワイプ可能なのでこのような判定にしてます。

発展:非同期通信の結果が格納された時にスワイプかどうか判定してtableを更新したい

   //非同期通信の結果受け取った後、画面更新したい際などにこのメソッド呼んであげる
   /*
   func swipeEndNotification() -> Void {
       if checkSwiping(){
           //スワイプ中なら行いたい処理
           DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
               // 1.0秒後に再度本メソッドを実行して再度終了しているかを確認する処理
               self.swipeEndNotification()
           }
       }else{
           //スワイプしていない時に行いたい時
           tableView.reloadData()
       }
   }
    */

現在Swipe中かどうかを判定して、Swipe中なら
再度1秒後に本メソッドを呼びます。

その後、Swipeではない状態であれば行いたい処理を行います。

この記事が気に入ったらサポートをしてみませんか?