繁体   English   中英

同时处理两个手势识别器

[英]Handle two Gesture Recognizer simultaneously

问题很简单:我有一个ViewController ,上面有一个GestureRecognizer

    panGR = UIPanGestureRecognizer(target: self,
              action: #selector(handlePan(gestureRecognizer:)))
    view.addGestureRecognizer(panGR)

在这个ViewController中,我还有一个class WhishlistTableViewController: UITableViewController我有“滑动删除”功能:

override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .destructive, title: "Löschen") {[weak self] _, _, completionHandler in
        self!.deleteWishDelegate?.deleteWish(indexPath)
    completionHandler(true)
    }
    deleteAction.backgroundColor = .red
    deleteAction.image = UIImage(systemName: "trash")
    let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
    configuration.performsFirstActionWithFullSwipe = false
    return configuration
}

这是我的panGR的视频: Screenvideo

这是我的handlePan function:

// handle swqipe down gesture
@objc private func handlePan(gestureRecognizer:UIPanGestureRecognizer) {
    // calculate the progress based on how far the user moved
    let translation = panGR.translation(in: nil)
    let progress = translation.y / 2 / view.bounds.height

  switch panGR.state {
  case .began:
    // begin the transition as normal
    self.dismissView()
    break
  case .changed:

    Hero.shared.update(progress)

  default:
    // finish or cancel the transition based on the progress and user's touch velocity
       if progress + panGR.velocity(in: nil).y / view.bounds.height > 0.3 {
        self.dismissView()
         Hero.shared.finish()
       } else {
         Hero.shared.cancel()
       }
  }
}

问题是这两者发生碰撞。 “滑动删除”仅在我禁用其他GestureRecognizer 为什么会这样,我该如何解决?

你应该试试这个。

class YourViewController: UIViewController, UIGestureRecognizerDelegate

在 viewDidLoad

yourGesture.delegate = self

最后

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true

    // If you wish to do conditionally.
    /*if (gestureRecognizer is UIPanGestureRecognizer || gestureRecognizer is UIRotationGestureRecognizer) {
        return true
    } else {
        return false
    }*/
}

当您在视图顶部执行平移手势时,将调用手势平移识别器。 如果 tableview 是视图的一部分,则当您尝试执行滑动删除 function 时,将调用手势 handlePan。

如果您想要 2 个单独的行为,则将您希望在其中执行手势 handlePan 的视图部分和您希望在其中执行滑动删除 function 的表格视图分开。

如下所示:

   panGR = UIPanGestureRecognizer(target: self,
          action: #selector(handlePan(gestureRecognizer:)))
   gestureView.addGestureRecognizer(panGR)
   view.addSubView(gestureView)

编辑:您还可以获得按下位置的位置/坐标,您可以计算要忽略的区域。

    currentLocation = gesture.location(in: self.view)
      

通常这很简单,

首先,您不需要在视图中添加手势识别器,

我们已经有了 function “touchesBegan”,它告诉这个 object 一个或多个新的触摸发生在一个视图或 window 中。

所以在你的代码中,你只需要使用它而不是手势识别器,它就可以工作。

class ViewController: UIViewController,UITableViewDataSource {
  
    
    let tableView:UITableView = {
     let table =  UITableView()
        table.backgroundColor = .blue
        table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        return table
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
    //    tableView.delegate = self
        tableView.dataSource = self
        view.addSubview(tableView)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        tableView.frame = CGRect(x: 0, y: view.frame.height/2, width: view.frame.width, height:view.frame.height/2 )
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          return 20
      }
      
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
          cell.backgroundColor = .blue
          return cell
      }
      

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else {
            return
        }// we store the touch
        
        let location = touch.location(in: view)//we retrieve the location of the touch
        
        if view.bounds.contains(location){//we check if our touch is inside our view
            
            // if our touch is inside  the view ,do the action you wanted to do with your gesture recognizer
            print("inside the view, outside tableView(Controller)")
        }else{
            // else here means here that  this is not inside the view, so it is inside  the tableView(Controller)
            // if this is not inside the view, you can select tableView,rows,swipe-to-delete etc, basically do whatever action you want with it
        }
    }
   
    
  
}



在 Mitesh Mistri 的帮助下,我得到了它的工作。 缺少的另一件事是 function 禁用tableView内的panGR ,否则用户将无法滚动。 这些是使它工作的两个 function:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if self.theTableView.view.bounds.contains(touch.location(in: self.theTableView.view)) {
        return false
    }
    return true
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM