显示ViewControllers之间的叠加视图

时间:2018-05-16 18:16:35

标签: ios swift view swift4

我尝试在成功登录后显示每个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?
    })
}

视图层次结构如下图所示。叠加视图应该覆盖所有内容。

Views hierarchy

1 个答案:

答案 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因为类可以被覆盖但静态不能。