简体   繁体   English

如何从另一个UIView向UIButton转发触摸?

[英]How can I forward touches to a UIButton from another UIView?

I have a UIButton and a UIView. 我有一个UIButton和一个UIView。 The View sits above the button, and is larger than the button in size. 视图位于按钮上方,并且大小比按钮大。 The view itself is what I want to have accept the touch events, and I'd like to forward them to the button, so that all the normal button visual changes on touch happen. 视图本身就是我想要接受触摸事件的内容,我想将它们转发到按钮,以便触摸所有正常按钮的视觉变化。

I can't seem to make this work-- my UIView implements touchesBegan/Moved/Ended/Cancelled, and turns around and calls the same methods on the button with the same arguments. 我似乎无法完成这项工作 - 我的UIView实现了touchesBegan / Moved / Ended / Cancelled,并转向并使用相同的参数调用按钮上的相同方法。 But the button doesn't respond. 但按钮没有响应。

I have ensured that the touch methods are in fact being called on the UIView. 我确保触摸方法实际上是在UIView上调用的。

Is there something obvious I'm missing here, or a better way of getting the control messages across? 有没有明显的东西我在这里丢失,或者更好的方法来获取控制消息? Or is there a good reason why this shouldn't work? 或者有一个很好的理由说明为什么这不起作用?

Thanks! 谢谢!

[Note: I'm not looking for workarounds for the view+button design. [注意:我不是在寻找视图+按钮设计的变通方法。 Let's assume that that's a requirement. 我们假设这是一个要求。 I'm interested in the notion of controls that are touch proxies for other controls. 我对作为其他控件的触摸代理的控件的概念感兴趣。 Thanks.] 谢谢。]

创建一个包含按钮并覆盖hitTest:withEvent:ContainerView ,以便它返回UIButton实例。

Are you sure your methods are being called? 你确定你的方法被调用了吗? If you haven't set userInteractionEnabled=YES, then it won't work. 如果你还没有设置userInteractionEnabled = YES,那么它将无法工作。

I've used such touch-forwarding before without problems, though, so I don't know why you're seeing the problems you're seeing. 我之前使用过这种触摸转发没有问题,所以我不知道为什么你会看到你遇到的问题。

I use the small class below when I need a larger touch target than the visual size of the button. 当我需要比按钮的视觉尺寸更大的触摸目标时,我使用下面的小类。

Usage: 用法:

let button = UIButton(...) // set a title, image, target/action etc on the button
let insets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
let buttonContainer = TouchForwardingButtonContainer(button: button, insets: insets) // this is what you add to your view
// a container view for a button that insets the button itself but forwards touches in the inset area to the button
// allows for a larger touch target than the visual size of the button itself
private class TouchForwardingButtonContainer: UIView {
    private let button: UIButton

    init(button: UIButton, insets: UIEdgeInsets) {
        self.button = button

        super.init(frame: .zero)

        button.translatesAutoresizingMaskIntoConstraints = false
        addSubview(button)
        let constraints = [
            button.topAnchor.constraint(equalTo: topAnchor, constant: insets.top),
            button.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -insets.bottom),
            button.leftAnchor.constraint(equalTo: leftAnchor, constant: insets.left),
            button.rightAnchor.constraint(equalTo: rightAnchor, constant: -insets.right)
        ]
        NSLayoutConstraint.activate(constraints)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("NSCoding not supported")
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        return button
    }
}

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

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