Swift - 如何将触摸事件传递给属于第二个 UIWindow 的多个按钮但忽略其他所有内容

Swift -How to pass touch events to multiple buttons that are part of a second UIWindow but ignore everything else

我按照 创建了一个按钮,它是第二个 window 的一部分,位于所有其他 windows 之上。它适用于 1 个按钮,因为它只允许那个按钮获取触摸事件,忽略第二个 window 内的所有其他内容,但它下面的主要 window 仍然接收所有触摸事件。

// This comment is from @robmayoff's answer
// As I mentioned, I need to override pointInside(_:withEvent:) so that the window ignores touches outside the button:

var button: UIButton?

private override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    guard let button = button else { return false }
    let buttonPoint = convertPoint(point, toView: button)
    return button.pointInside(buttonPoint, withEvent: event)
}

我现在在 SecondWindow 中使用它的方式,我可以接收 cancelButton 的触摸事件,但其他按钮会与其他所有按钮一起被忽略。 问题是我如何接收第二个 window 内其他按钮的触摸事件,但仍然忽略其他所有内容?

第二个 UIWindow。这是我尝试过但没有用的方法:

class SecondWindow: UIWindow {

    var cancelButton: UIButton?
    var postButton: UIButton? // I need this to also receive touch events
    var reloadButton: UIButton? // I need this to also receive touch events

    init() {
        super.init(frame: UIScreen.main.bounds)
        backgroundColor = nil
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {

        if let cancelButton = cancelButton {
            let cancelButtonPoint = convert(point, to: cancelButton)
            return cancelButton.point(inside: cancelButtonPoint, with: event)
        }

        if let postButton = postButton {
            let postButtonPoint = convert(point, to: postButton)
            return postButton.point(inside: postButtonPoint, with: event)
        }

        if let reloadButton = reloadButton {
            let reloadButtonPoint = convert(point, to: reloadButton)
            return reloadButton.point(inside: reloadButtonPoint, with: event)
        }

        return false
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let hitView = super.hitTest(point, with: event)
        guard let safeHitView = hitView else { return nil }
        if safeHitView.isKind(of: SecondController.self) { return nil }
        return safeHitView
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

vc 与按钮:

class SecondController: UIViewController {

    lazy var cancelButton: UIButton = { ... }()

    lazy var postButton: UIButton = { ... }()

    lazy var reloadButton: UIButton = { ... }()

    let window = SecondWindow()

    init() {
        super.init(nibName: nil, bundle: nil)

        window.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)

        window.cancelButton = cancelButton
        window.postButton = postButton
        window.reloadButton = reloadButton

        window.isHidden = false
        window.backgroundColor = .clear
        window.rootViewController = self
        window.windowLevel = UIWindow.Level.normal
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .clear

        // Anchors for buttons
    }
}

我检查触摸点是否在接收器内部(触摸哪个按钮)。如果是 returns true 则触摸被确认并且按钮响应,如果不是它什么都不做并跳到下一个按钮,在那里检查并重复该过程直到最后一个按钮并重复相同的过程。

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {

    guard let cancelButton = cancelButton, let postButton = postButton, let reloadButton = reloadButton else {
        return false
    }

    let cancelButtonPoint = convert(point, to: cancelButton)
    let cancelBool = cameraButton.point(inside: cameraButtonPoint, with: event)
    if cancelBool {
        return cancelButton.point(inside: cancelButtonPoint, with: event)
    }

    let postButtonPoint = convert(point, to: postButton)
    let postBool = postButton.point(inside: postButtonPoint, with: event)
    if postBool {
        return postButton.point(inside: postButtonPoint, with: event)
    }

    let reloadButtonPoint = convert(point, to: reloadButton)
    return reloadButton.point(inside: reloadsButtonPoint, with: event)
}