我在 UIKit 中使用 UIView 在 Android 中创建类似 Toast 的功能。
我使用的方法是'bringSubviewToFront'。但是这个方法有一个问题,在切换ViewController到tab、push、present的时候,不会保持原来的位置。
所以我采用了在窗口中添加自己的UIView的方法
guard let window = UIApplication.shared.windows.last else { return }
window.addSubview(toastView)
这样,切换tab时,即使进行了push,UIView也不会消失,仍然显示。然而,问题是 UIView 在呈现另一个 View Controller 时被隐藏了。
当我从顶视图控制器添加 UIView 并关闭顶视图控制器时,添加的 UIView 的行为类似于 Toast。
就是说只有在Window上添加UIView,presenting另一个View Controller时才会出现隐藏的问题,请问有什么办法可以解决这个问题吗?
我想让 UIView 在任何情况下都保持在顶部。
一个解决方案是使用自定义
UIWindow
类,让您指定一个视图保持在顶部。
开始于:
class MyWindow: UIWindow {
var topView: UIView? {
didSet {
if let topView {
// Make sure the view is actually assigned to this window
if topView.window === self {
bringSubviewToFront(topView)
} else {
self.topView = nil
}
}
}
}
override func addSubview(_ view: UIView) {
super.addSubview(view)
if let topView {
bringSubviewToFront(topView)
}
}
override func willRemoveSubview(_ subview: UIView) {
if let topView, subview === topView {
self.topView = nil
}
super.willRemoveSubview(subview)
}
override func bringSubviewToFront(_ view: UIView) {
super.bringSubviewToFront(view)
if let topView, view !== topView {
super.bringSubviewToFront(topView)
}
}
}
然后更改 AppDelegate 和/或 SceneDelegate 中的任何
UIWindow
引用以使用 MyWindow
而不是 UIWindow
.
然后,一旦您创建了要保留在顶部的视图并将其像往常一样添加到视图层次结构中,最后一次调用以设置窗口的
topView
.
guard let window = UIApplication.shared.windows.last else { return }
window.addSubview(toastView) // Only do this is the view is not part of any other view hierarchy attached to the window
window.topView = toastView
请注意,此解决方案不考虑可能在比主窗口更高级别添加到应用程序的任何其他窗口。
你已经添加了窗口,这就是为什么它显示给整个控制器,
请看下面的代码,
let firstView = UIView()
firstView.frame = CGRect(x: 20, y: 20, width: 250, height: 300)
firstView.backgroundColor = .red
view.addSubview(firstView)
let secondView = UIView()
secondView.frame = CGRect(x: 40, y: 40, width: 250, height: 300)
secondView.backgroundColor = .blue
view.addSubview(secondView)
注意:最后的视图将显示在顶部