如何防止UITableViewCell内部的手势干扰UITableView的滚动?

时间:2018-07-31 15:47:35

标签: ios swift uitableview uiview

我觉得这个问题以前已经被问过无数次了,但是我已经搜寻了好几天了,所以找不到有效的解决方案。在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 个答案:

答案 0 :(得分: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  }

    .....
}