I followed this answer to create a button that is part of a second window that is on top of all other windows. It works fine with 1 button because it allows only that one button to get touch events, ignores everything else inside the second window, but the main window underneath of it still receives all of it touch events.
// 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)
}
The way I have it now inside the SecondWindow, I can receive touch events for the cancelButton
but the other buttons get ignored along with everything else. The question is how do I receive touch events for the other buttons inside the second window but still ignore everything else?
The Second UIWindow. This is what I tried but it didn't work:
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")
}
}
The vc with the buttons:
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
}
}