ios - 在 ViewController 之间显示叠加 View

标签 ios swift view swift4

我试图在成功登录后在每个 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 应该覆盖所有内容。

Views hierarchy

最佳答案

如果您的要求是在所有 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/

相关文章:

ios - Swift 多个 subview 并返回原始 TableView

python - 如何在 View 中访问 pk (Django)

ios - 如何在 Swift 中返回带有边缘情况的单个值?

ios - 更新您的应用程序是否会保存用户以前的 Plist 文件?

swift - 无法构建或存档运行良好的 Xcode 项目

swift - Algolia helper searcher方法Filter不过滤字符串,只过滤数字

android - 如何为新 fragment 重用 fragment View

java - 在动画期间更改 Z 顺序

ios - 从视频 AVFoundation 中提取音频

ios - 无效签名错误!