Swift:UIScrollView 和 UIControl - addTarget | addGestureRecognizer - 没有按预期工作

Posted

技术标签:

【中文标题】Swift:UIScrollView 和 UIControl - addTarget | addGestureRecognizer - 没有按预期工作【英文标题】:Swift: UIScrollView & UIControl - addTarget | addGestureRecognizer - Not working as expected 【发布时间】:2019-12-22 09:00:38 【问题描述】:

我正在使用UIScrollViewUIStackView 水平滚动并选择UIControl 元素。

我在 UIControl 元素上设置了 addTarget,如下所示在 UIStackView 内: 即HighlightColorView的类型为UIControl

lazy var colorsStackView: UIStackView = 
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.distribution = .fillEqually
        stackView.isUserInteractionEnabled = true
        stackView.alignment = .center
        stackView.spacing = 12
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.isUserInteractionEnabled = true
        for color in colors 
            let colorView = HighlightColorView()
            colorView.backgroundColor = color
            colorView.addTarget(self, action: #selector(self.handleColorTap(_:)), for: .touchUpInside)
            stackView.addArrangedSubview(colorView)
        
        return stackView
    ()

@objc func handleColorTap(_ sender: UIView) 
        highlightSelectionDelegate.didTapColor(colorView: sender, mainView: self)
        let viewBackgroundColor = sender.backgroundColor ?? .black
        print("????", viewBackgroundColor)
    

问题是当您点击colorView 类型为UIControl 时,点击无法按预期工作。似乎有一个冻结,它仅在视图被关闭时才有效。 基本上,您点击颜色并没有任何反应,然后当您关闭视图时,点击注册并开始工作。 这似乎是滚动视图的问题,但我不确定。

scrollView的实现:

lazy var scrollView: UIScrollView = 
        let scView = UIScrollView()
        scView.contentInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
        scView.showsHorizontalScrollIndicator = false
        scView.translatesAutoresizingMaskIntoConstraints = false
        scView.isUserInteractionEnabled = true
        scView.delaysContentTouches = false
        return scView
    ()

能够滚动颜色并点击它们以突出显示文本的用例。

【问题讨论】:

【参考方案1】:

我注意到的一件事是您可能指的是UITapGestureRecognizer。如果您单独使用UIGestureRecognizer,则它不会起作用。

     let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleColorTap))
     view.addGestureRecognizer(tapRecognizer)

回答你提出的问题

UIGestureRecognizer 用于单个视图。 @TomSwift 的回答。 我认为这适用于您使用多个视图的情况。将addTargetaddGestureRecognizer 设置为仅一个视图。

如果您使用多个视图,例如在 UIStackView 内有 UIControlUIScrollView 内有 UIStackView 的情况下,您需要确保 addTargetaddGestureRecognizer 是仅设置为 views 之一。

由于您希望UIControl 响应点击,您需要仅在此视图上设置addTarget,而不是在UIScrollView 和/或UIStackView

for color in colors 
    let colorView = HighlightColorView()
    colorView.backgroundColor = color
    colorView.addTarget(self, action: #selector(handleColorTap(_:)), for: .touchUpInside)
    colorsStackView.addArrangedSubview(colorView)
  

注意:您不必将代码放在viewDidLoad function 中,它在哪里就可以了。只需从您的视图中删除额外的 addTargetaddGestureRecognizer

【讨论】:

以上是关于Swift:UIScrollView 和 UIControl - addTarget | addGestureRecognizer - 没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

如何使在Swift中使用UIScrollView进行滚动和缩放

Swift如何获得UIScrollView动态高度

Swift - UIImageView 缩放比 UIScrollView 更大

swift 3中的错误UIScrollView

UIScrollView 中的 Swift-Xcode UILabel

滚动时将功能分配给 UIScrollView (Swift)