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)
}
我按照
// 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)
}