ios - Swift - 如何将触摸事件传递给多个按钮,这些按钮是第二个 UIWindow 的一部分,但忽略其他所有内容
问题描述
我按照这个答案创建了一个按钮,该按钮是位于所有其他窗口之上的第二个窗口的一部分。它适用于 1 个按钮,因为它只允许一个按钮获取触摸事件,忽略第二个窗口内的所有其他内容,但其下方的主窗口仍然接收所有触摸事件。
// 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
但其他按钮与其他所有按钮一起被忽略。问题是我如何接收第二个窗口内其他按钮的触摸事件但仍然忽略其他所有内容?
第二个 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
}
}
解决方案
我检查触摸的点是否在接收器内部(无论触摸哪个按钮)。如果返回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)
}
推荐阅读
- c++ - 在串行端口(QtSerialPort)读取传入字节的连续流
- javascript - 为什么单击事件会被多个鼠标事件阻止?
- next.js - Vercel 无服务器功能未运行 axios 发布请求
- arrays - 在C中为char数组赋值
- python - Python 3.9.5 和 Python 3.9.6 上 datetime.astimezone 的不同行为
- javascript - 加载脚本时出现内容安全策略错误
- windows - 为什么无法出现控制窗口?
- php - 失败:代码:404 值:未找到详细信息(如果有):未找到段“作业”Microsoft Azure [Blob 创建] PHP SDK 的资源
- notion-api - Notion API - Update Relation Support
- swift - SpriteKit SKScene not resizing correctly to fit iPhone 12