我尝试在成功登录后显示每个ViewController顶部的叠加视图,以显示应用的加载状态,并在显示此视图时加载一些数据。 此视图来自自定义NIB文件。
我在向服务器成功登录请求后显示OverlayLoadingView,然后我想在另一个Storyboard上使用以下内容呈现新的ViewController:
self.present(vc, animated: true, completion: nil)
最后在下一个ViewController中隐藏OverlayLoadingView(这就是我将它作为Singleton处理的原因)。
但是当我呈现下一个ViewController时,OverlayLoadingView消失了。有没有办法在所有内容上显示此加载视图,同时在后面呈现新的视图控制器?
这样的事情:
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()
}
}
编辑:
要显示我正在使用的叠加层视图:
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?
})
}
视图层次结构如下图所示。叠加视图应该覆盖所有内容。
答案 0 :(得分:2)
如果您要求在所有控制器上方显示加载视图,则可以将视图添加到窗口中。
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()
}
顺便说一下,这不是Singleton,因为我能够使用init并创建另一个实例,将init标记为私有。使类最终避免反射并将class
替换为static
因为类可以被覆盖但静态不能。