隐形按钮无法响应被点击

问题描述 投票:0回答:2

我试图在图像视图上放置一个隐形按钮,因为图像视图太小而无法响应轻击手势识别器。我不能只是让图像变得更大而且看起来很糟糕。这是用于增加数量的imageview的代码:

private func configureIncreaseQuantityImageView() {
    increaseQuantityImageView.contentMode = .scaleAspectFill
    increaseQuantityImageView.image = UIImage(named: "arr_up")
    //increaseQuantityImageView.isUserInteractionEnabled = true
    //increaseQuantityImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleIncreaseQuantityTapped)))
    contentView.addSubview(increaseQuantityImageView)
    increaseQuantityImageView.translatesAutoresizingMaskIntoConstraints = false
    increaseQuantityImageView.centerYAnchor.constraint(equalTo: verticalDivider.centerYAnchor).isActive = true
    increaseQuantityImageView.leftAnchor.constraint(equalTo: verticalDivider.rightAnchor, constant: 12).isActive = true
    increaseQuantityImageView.widthAnchor.constraint(equalToConstant: 12).isActive = true
    increaseQuantityImageView.heightAnchor.constraint(equalToConstant: 8).isActive = true
}

以下是不响应触摸的隐形按钮的代码:

private func configureInvisibleIncreaseQuantityButton() {
    invisibleIncreaseQuantityButton.backgroundColor = .clear
    invisibleIncreaseQuantityButton.addTarget(self, action: #selector(handleIncreaseQuantityTapped), for: .touchUpInside)
    contentView.addSubview(invisibleIncreaseQuantityButton)
    invisibleIncreaseQuantityButton.translatesAutoresizingMaskIntoConstraints = false
    invisibleIncreaseQuantityButton.centerYAnchor.constraint(equalTo: verticalDivider.centerYAnchor).isActive = true
    invisibleIncreaseQuantityButton.leftAnchor.constraint(equalTo: verticalDivider.rightAnchor).isActive = true
    invisibleIncreaseQuantityButton.widthAnchor.constraint(equalToConstant: 35).isActive = true
    invisibleIncreaseQuantityButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
}

这是触摸隐形按钮时不会调用的函数。我为减少数量按钮做了一些非常相似的事情,因此无需显示该代码。

@objc private func handleIncreaseQuantityTapped() {
    self.quantity += 1
    quantityValueLabel.text = "\(self.quantity)"
    self.menuItem?.quantity = self.quantity
    guard let item = self.menuItem else { return }
    delegate?.updateMenuItem(item)
}
ios swift uitableview uibutton
2个回答
0
投票

Swift 4.2

你可以在UITapGestureRecognizer的superview上添加imageView,并设置一个包含imageView位置的范围。 例如:

let superviewOfImageView = UIView()
let imageView = UIImageView()

func setupTapGesture() {
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap(_:)))
    superviewOfImageView.addGestureRecognizer(tapGesture)
}

@objc func didTap(_ gesture: UITapGestureRecognizer) {
    // user's finger tap at superview's location.
    let point = gesture.location(in: superviewOfImageView)

    // set the range you want.
    let width = superviewOfImageView.frame.width/4 
    let height = superviewOfImageView.frame.height/4
    let boundaryOfImageView = CGRect(x: 0, y: 0, width: width, height: height)

    // if in the range you set, do what ever you want.
    if boundaryOfImageView.contains(point) {
        // do something here.
    }
}

祝你好运,我的朋友!


0
投票

一般来说,您不需要按钮就可以执行此操作。只需使用分层在对象上的UIView,即可完成同样的任务。

但是,在以编程方式执行此操作时,有一些注意事项,主要是,您实际上看不到UI对象所在的位置,因为它全部是在代码而不是故事板中处理的。

我的建议:1)您的视图可能未启用用户交互increaseQuantityImageView.isUserInteractionEnabled = true

2)您尝试与之交互的视图隐藏在子视图层次结构中的另一个视图后面

.addSubview()函数可以将您想要触摸的对象放置在它应该覆盖的对象下。

这是一个漂亮的小片段,我用它来很快找到子视图:

此函数将提供的视图中包含的所有子视图作为数组返回。

private func getSubviewsOf<T : UIView>(view:UIView) -> [T] {
        var subviews = [T]()

        for subview in view.subviews {
            subviews += getSubviewsOf(view: subview) as [T]

            if let subview = subview as? T {
                subviews.append(subview)
            }
        }
        return subviews
    }

你可以像这样使用它:

// First, let's get an ID on the object you are trying to find
`invisibleDecreaseQuantityButton.restorationIdentifier = "targetView"`

// Then, also set a restoration ID on the view that this targetView is supposed to be on top of
increaseQuantityImageView.restorationIdentifier = "coveredView"

// Now, get all of the subviews of the main view
let subviews = self.getSubViewsOf(view: self.view)

var targetViewIndex = 0
var coveredViewIndex = 0
// Figure out which view is the correct one
for (index, view) in subviews.enumerated() {

    // When we find the target view
    if view.restorationIdentifier == "targetView" {
        // Let's print it so we know where it resides
        print("targetView's index: \(index)")
        targetViewIndex = index
    }

    if view.restorationIdentifier == "coveredView"{
        // print this one too
        print("coveredView's index: \(index)")
        coveredViewIndex = index
    }
}

这部分实际上只是为了帮助您以编程方式进行调试。如果你想在你的应用程序中获得更直观的调试方法,我强烈推荐FLEX。使用此框架,您可以直观地点击每个元素并获取其变量名称,并在视图控制器中直观地查看包含整个视图层次结构的图形。

请记住,在视图层次结构中,子视图数组中具有较低索引的视图意味着它更接近视图的顶部。所以:

if targetIndex > coveredViewIndex {
    // push the coveredView behind the targetView
    self.view.insertSubview(targetView, at: coveredViewIndex)
}

更多关于Apple Documentation的层次结构

Lmk如果我可以帮你进一步调试。这是我刚刚制作的FLEX的小屏幕,它是一个很棒的工具:

© www.soinside.com 2019 - 2024. All rights reserved.