如何防止 UITableViewCell 内的手势干扰 UITableView 的滚动?
Posted
技术标签:
【中文标题】如何防止 UITableViewCell 内的手势干扰 UITableView 的滚动?【英文标题】:How to prevent a gesture inside a UITableViewCell from interfering with the UITableView's scrolling? 【发布时间】:2018-07-31 15:47:34 【问题描述】:我觉得这个问题之前已经被问过很多次了,但是我已经找了好几天了,找不到有效的解决方案。在 Swift 4 中,我有一个 UITableView,其中每个 UITableViewCell 里面都有可触摸的 UIView。这个 UIView 附加了一个 UILongPressGestureRecognizer ,它会影响其按下状态并在按下时导航到另一个屏幕。所有的行都相对靠近,不幸的是,为了启动平移手势来滚动 UITableView,您必须按下列表项,这会触发其手势识别器并立即离开页面。
原来,你不能按下 UITableViewCell 来触发滚动,所以我在我的 UIView 中设置了手势委托并添加了这个功能:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
return true
因此导致了我目前遇到的问题。这是我在 UITableViewCell 中使用的自定义 UIView 类:
import Foundation
import UIKit
protocol ItemViewDelegate: AnyObject
func tapped()
class ItemView: UIView, UIGestureRecognizerDelegate
weak var delegate: ItemViewDelegate?
var parent: UIViewController?
override init(frame: CGRect)
super.init(frame: frame)
self.initializeGestureRecognition()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
self.initializeGestureRecognition()
lazy var animator: UIViewPropertyAnimator =
let cubicParameters = UICubicTimingParameters(controlPoint1: CGPoint(x: 0, y: 0.5), controlPoint2: CGPoint(x: 1.0, y: 0.5))
let animator = UIViewPropertyAnimator(duration: 0.1, timingParameters: cubicParameters)
animator.isInterruptible = true
return animator
()
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
return true
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool
if (type(of: otherGestureRecognizer) == UIPanGestureRecognizer.self)
return true
return false
private func initializeGestureRecognition()
let tapRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.handleTap(from:)))
tapRecognizer.minimumPressDuration = 0
tapRecognizer.delegate = self
tapRecognizer.cancelsTouchesInView = false
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tapRecognizer)
private func tapped()
guard let delegate = self.delegate else
return
delegate.tapped()
override func layoutSubviews()
super.layoutSubviews()
self.roundCorners(radius: 4)
self.addShadow(opacity: 0.06, radius: 4)
@objc func handleTap(from recognizer: UITapGestureRecognizer)
switch recognizer.state
case .began:
if animator.isRunning
animator.stopAnimation(true)
animator.addAnimations
self.transform = CGAffineTransform(scaleX: 0.98, y: 0.98)
animator.startAnimation()
case .ended:
if animator.isRunning
animator.stopAnimation(true)
animator.addAnimations
self.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
animator.startAnimation()
self.tapped()
default:
break
我认为 shouldRequireFailureOf
覆盖肯定会起作用,正如 Apple 的文档所暗示的那样,但我现在已经尝试了几乎所有方法,并且正在拔头发。任何帮助,将不胜感激。谢谢!
【问题讨论】:
【参考方案1】:你可以在包含 tableView 的 VC 中定义这个 var
var isScrolling = false
//
class ViewController: UIViewController , UIScrollViewDelegate
//
func scrollViewWillBeginDragging(_ scrollView: UIScrollView)
isScrolling = true
func scrollViewDidScroll(_ scrollView: UIScrollView)
isScrolling = false
//
在单元格内读取这个值
@objc func handleTap(from recognizer: UITapGestureRecognizer)
if parentVc.isScrolling return
.....
【讨论】:
这种方法似乎不起作用......不幸的是,当用户从视图中抬起手指时,isScrolling 已被设置回 false,并且无论如何都会处理点击事件。跨度>以上是关于如何防止 UITableViewCell 内的手势干扰 UITableView 的滚动?的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 内的 UITextField - 防止文本重置的方法
如何将手势识别器添加到 UITableViewCell 的 UIImage 和 UIButton?