代码之家  ›  专栏  ›  技术社区  ›  Said-Abdulla Atkaev

另一个可单击SecondViewController的SecondViewController上的FirstViewController

  •  0
  • Said-Abdulla Atkaev  · 技术社区  · 6 年前

    我正在尝试创建通用警报,它显示在最顶部的视图控制器上,而底部的视图控制器仍然可以单击。

    1 回复  |  直到 6 年前
        1
  •  2
  •   iOSer    6 年前

    请注意,我不使用情节提要或XIB 此外,如果您的目标是iOS11及更高版本,则在使用autolayout代码时需要使用safeAreaLayoutGuide

    解决方案是两个方面。

    然后创建一个新的swift文件,NSObject的一个子类。假设NetworkAlerter.swift并复制粘贴下面的代码(视情况而定)

    import UIKit
    
    class NetworkAlerter: NSObject {
    
    var window :UIWindow? = UIApplication.shared.keyWindow
    
    var alertShowingConstraint : NSLayoutConstraint?
    var alertHidingConstraint : NSLayoutConstraint?
    
    var closeTimer : Timer? = nil
    
    public lazy var networkIndicatorLabel : UILabel = {
        let label : UILabel = UILabel(frame: .zero)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = NSTextAlignment.center
        return label
    }()
    
    
    override init() {
        super.init()
        createSubviews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        print("Time to deinit")
        networkIndicatorLabel.removeFromSuperview()
    }
    
    func createSubviews() {
        guard let window = window else {
            print("Some thing wrong with Window initialization!!")
            return
        }
        window.addSubview(networkIndicatorLabel)
        addAutolayout()
    }
    
    func addAutolayout() {
        guard let window = window else {
            print("Some thing wrong with Window initialization!!")
            return
        }
        alertShowingConstraint = networkIndicatorLabel.topAnchor.constraint(equalTo: window.topAnchor)
        alertHidingConstraint = networkIndicatorLabel.bottomAnchor.constraint(equalTo: window.topAnchor)
        alertHidingConstraint?.isActive = true
        networkIndicatorLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
        networkIndicatorLabel.leadingAnchor.constraint(equalTo: window.leadingAnchor).isActive = true
        networkIndicatorLabel.trailingAnchor.constraint(equalTo: window.trailingAnchor).isActive = true
    }
    
    func showNetworkAlerter(networkAvailable: Bool) {
        guard let window = window else {
            print("Some thing wrong with Window initialization!!")
            return
        }
        invalidateAndKillTimer()
        closeTimer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(dismissNetworkAlerter), userInfo: nil, repeats: false)
    
        if networkAvailable {
            networkIndicatorLabel.text = "Available"
            networkIndicatorLabel.backgroundColor = UIColor.green
        } else {
            networkIndicatorLabel.text = "Not Available"
            networkIndicatorLabel.backgroundColor = UIColor.red
        }
    
        window.layoutIfNeeded()
        UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseOut, animations: {
            if (self.alertHidingConstraint?.isActive)! {
                self.alertHidingConstraint?.isActive = false
            }
            if !(self.alertShowingConstraint?.isActive)! {
                self.alertShowingConstraint?.isActive = true
            }
            window.layoutIfNeeded()
        }, completion: { _ in
        })
    }
    
    @objc func dismissNetworkAlerter() {
        invalidateAndKillTimer()
        guard let window = window else {
            print("Some thing wrong with Window initialization!!")
            return
        }
        window.layoutIfNeeded()
        UIView.animate(withDuration: 0.5, animations: {
            if (self.alertShowingConstraint?.isActive)! {
                self.alertShowingConstraint?.isActive = false
            }
            if !(self.alertHidingConstraint?.isActive)! {
                self.alertHidingConstraint?.isActive = true
            }
            window.layoutIfNeeded()
        }) { (done) in
        }
    }
    
    // MARK:- Timer Related
    private func invalidateAndKillTimer() -> Void {
        if (closeTimer != nil) {
            closeTimer?.invalidate()
            closeTimer = nil
        }
    }
    

    }

    var networkAlertLauncher : NetworkAlerter? = nil
    

    func showAlertBar(networkAvailabilityStatus: Bool) -> Void {
            if networkAlertLauncher != nil {
                networkAlertLauncher = nil
            }
    
            networkAlertLauncher = NetworkAlerter()
            networkAlertLauncher?.showNetworkAlerter(networkAvailable: networkAvailabilityStatus)
        }
    

    现在,可以从从基本视图控制器扩展的所有视图控制器访问showAlertBar函数。你可以这样调用它: self.showAlertBar(networkAvailabilityStatus: false) self.showAlertBar(networkAvailabilityStatus: true)