我试图在成功登录后在每个 ViewController 的顶部显示一个叠加 View ,以显示应用程序的加载状态并在显示此 View 时加载一些数据。 此 View 来自自定义 NIB 文件。
我在向服务器成功登录请求后显示 OverlayLoadingView,然后我想使用以下方法在另一个 Storyboard 上呈现一个新的 ViewController:
self.present(vc, animated: true, completion: nil)
最后将 OverlayLoadingView 隐藏在下一个 ViewController 中(这就是我将其作为单例处理的原因)。
但是当我呈现下一个 ViewController 时,OverlayLoadingView 消失了。有没有办法在所有内容之上显示这个加载 View ,同时在背面呈现一个新的 View Controller ?
像这样:
LoginViewController -> 登录成功 -> 显示OverlayView -> 呈现MainViewController -> MainViewController呈现在OverlayView下方 -> 加载初始数据 -> 加载初始数据后隐藏OverlayView。
@IBDesignable
public class OverlayLoadingView: UIView {
@IBOutlet weak var headerImageView: UIImageView!
@IBOutlet weak var detailTextLabel: UILabel!
class var sharedInstance: OverlayLoadingView {
struct Static {
static let instance: OverlayLoadingView = OverlayLoadingView(frame: UIScreen.main.bounds)
}
return Static.instance
}
// Custom view from the XIB file
fileprivate var view: UIView!
// Set header image directly by giving a value to headerImageURL variable from server response
/**
Initialiser method
*/
override init(frame: CGRect) {
super.init(frame: frame)
setupNib()
}
/**
Initialiser method
*/
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupNib()
}
fileprivate func loadNib() -> UIView? {
return Bundle.main.loadNibNamed("OverlayLoadingView", owner: self, options: nil)?.first as? UIView
}
func setupNib() {
if let overlayLoadingView = loadNib() {
self.view = overlayLoadingView
let screenWidth = Util.screenSize().width
let screenHeight = Util.screenSize().height
self.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
self.addSubview(view)
}
}
public func showOverlay() {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
let window = appDelegate.window {
self.alpha = 1.0
window.addSubview(self)
activityIndicator.startAnimating()
}
}
public func hideOverlayView() {
activityIndicator.stopAnimating()
self.removeFromSuperview()
}
}
编辑:
要显示我正在使用的覆盖 View :
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "TabMenu", bundle: nil)
let vc = storyboard.instantiateInitialViewController()!
OverlayLoadingView.sharedInstance.showOverlay()
self.present(vc, animated: true, completion: {
// Dismiss current VC?
})
}
View 层次结构如下图所示。覆盖 View 应该覆盖所有内容。
最佳答案
如果您的要求是在所有 Controller 上方显示加载 View ,您可以将 View 添加到窗口。
if let window = UIApplication.shared.keyWindow {
let overlay = OverlayLoadingView(frame:UIScreen.main.bounds)
overlay.tag = 1001
window.addSubView(overlay)
// remove it like this
window.viewWithTag(overlay.tag)?.removeFromSuperView()
}
顺便说一句,这不是单例,因为我可以使用 init 并创建另一个实例,将 init 标记为私有(private)。将类设置为 final 以避免反射,并将 class
替换为 static
因为可以覆盖 class 而不能覆盖 static。
关于ios - 在 ViewController 之间显示叠加 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50377583/