自定义警报消息覆盖

时间:2021-05-02 10:46:15

标签: swift struct uialertview uialertcontroller

我的模型:

struct Model : Codable {
    let title : String
    var target : Int
    var read : Int
    let mean : String
    let useful : String
}

然后我创建自定义警报消息模型:

class MyAlert  {
    struct Constants {
        static let backgroundAlphaTo : CGFloat = 0.6
    }

    private var backgroundView : UIView = {
        let backgroundView = UIView()
        backgroundView.backgroundColor = .black
        backgroundView.alpha = 0
        return backgroundView
    }()

    private let alertView : UIView = {
        let alertView = UIView()
        alertView.backgroundColor = .white
        alertView.layer.masksToBounds = true
        alertView.layer.cornerRadius = 12
        return alertView
    }()
    
    private var myTargetView : UIView?
    
    func showAlert(with title :String , message : String , on ViewController : UIViewController){
        guard let targetView = ViewController.view else {
            return
        }
        myTargetView = targetView
        
        backgroundView.frame = targetView.bounds
        targetView.addSubview(backgroundView)
        targetView.addSubview(alertView)
        
        alertView.frame = CGRect(
            x: 40, y: -300, width: targetView.frame.size.width-80, height: 300
        )
        
        let titleLabel = UILabel(frame: CGRect(
                                    x: 0,
                                    y: 0,
                                    width: alertView.frame.size.width,
                                    height: 80))
        titleLabel.text = title
        titleLabel.textAlignment = .center
        alertView.addSubview(titleLabel)
        
        
        let messageLabel = UILabel(frame: CGRect(
                                    x: 0,
                                    y: 80,
                                    width: alertView.frame.size.width,
                                    height: 170))
        
        messageLabel.numberOfLines = 0
        messageLabel.text = message
        messageLabel.textAlignment = .center
        alertView.addSubview(messageLabel)
        
        let button = UIButton(frame: CGRect(
                                x: 0,
                                y: alertView.frame.size.height-50,
                                width: alertView.frame.size.width,
                                height: 50))
        
        alertView.addSubview(button)
        button.setTitle("Kapat", for: .normal)
        button.setTitleColor(.blue, for: .normal)
        button.addTarget(self, action: #selector(dissmissAlert), for: .touchUpInside)
        
        UIView.animate(withDuration: 0.25) {
            self.backgroundView.alpha = Constants.backgroundAlphaTo
        } completion: { (done) in
            if done {
                UIView.animate(withDuration: 0.25) {
                    self.alertView.center = targetView.center
                }
            }
        }
    }
    
    @objc  func dissmissAlert() {
        guard let targetView = myTargetView else {
            return
        }
        
        UIView.animate(withDuration: 0.25, animations: {
            self.alertView.frame = CGRect(
                x: 40, y: targetView.frame.size.height, width: targetView.frame.size.width-80, height: 300
                
            )}, completion: {done in
                if done {
                    UIView.animate(withDuration: 0.25, animations: {
                        self.backgroundView.alpha = 0
                    }, completion: {done in
                        if done {
                            self.alertView.removeFromSuperview()
                            self.backgroundView.removeFromSuperview()
                        }
                        
                    })
                }
                
            }
        )
    }
}

我有 segmentController :

@objc func ButtonTapped( _ sender : UISegmentedControl) {
    if sender.selectedSegmentIndex == 1 {
        customAlert.showAlert(with: zikirs.title, message: zikirs.mean, on: self)
    } else if sender.selectedSegmentIndex == 2 {
        customAlert.showAlert(with: zikirs.title, message: zikirs.useful, on: self)
    }
}

private func dismissAlert(){
    customAlert.dissmissAlert()
}

这里的问题是第一条消息是正常的,但第二条消息覆盖了另一条消息。 enter image description here

我该如何克服这个问题。我认为这是来自类的继承属性。但我想用 Struct 做我的 CustomAlert 模型,因为@objc 只能是类

1 个答案:

答案 0 :(得分:0)

问题是您没有从 alertView 中删除标签和按钮,而是在下次调用时添加新的。

我的建议是为视图分配标签并仅在第一次创建它们

class MyAlert  {
    struct Constants {
        static let backgroundAlphaTo : CGFloat = 0.6
    }

    private var backgroundView : UIView = {
        let backgroundView = UIView()
        backgroundView.backgroundColor = .black
        backgroundView.alpha = 0
        return backgroundView
    }()

    private let alertView : UIView = {
        let alertView = UIView()
        alertView.backgroundColor = .white
        alertView.layer.masksToBounds = true
        alertView.layer.cornerRadius = 12
        return alertView
    }()
    
    private var myTargetView : UIView?
    
    func showAlert(with title :String , message : String , on ViewController : UIViewController){
        guard let targetView = ViewController.view else {
            return
        }
        myTargetView = targetView
        
        backgroundView.frame = targetView.bounds
        targetView.addSubview(backgroundView)
        targetView.addSubview(alertView)
        
        alertView.frame = CGRect(
            x: 40, y: -300, width: targetView.frame.size.width-80, height: 300
        )
        
        if let titleLabel = alertView.viewWithTag(100) as? UILabel {
             titleLabel.text = title
        } else {      
            let titleLabel = UILabel(frame: CGRect(
                x: 0,
                y: 0,
                width: alertView.frame.size.width,
                height: 80))
            titleLabel.tag = 100
            titleLabel.text = title
            titleLabel.textAlignment = .center
            alertView.addSubview(titleLabel)
        }
        
        if let messageLabel = alertView.viewWithTag(101) as? UILabel {
            messageLabel.text = message
        } else {
            let messageLabel = UILabel(frame: CGRect(
                x: 0,
                y: 80,
                width: alertView.frame.size.width,
                height: 170))
            
            messageLabel.tag = 101
            messageLabel.numberOfLines = 0
            messageLabel.text = message
            messageLabel.textAlignment = .center
            alertView.addSubview(messageLabel)
        }
        
        if alertView.viewWithTag(102) == nil {
            let button = UIButton(frame: CGRect(
                x: 0,
                y: alertView.frame.size.height-50,
                width: alertView.frame.size.width,
                height: 50))
            
            button.tag = 102
            alertView.addSubview(button)
            button.setTitle("Kapat", for: .normal)
            button.setTitleColor(.blue, for: .normal)
            button.addTarget(self, action: #selector(dissmissAlert), for: .touchUpInside)
        }
        
        UIView.animate(withDuration: 0.25) {
            self.backgroundView.alpha = Constants.backgroundAlphaTo
        } completion: { (done) in
            if done {
                UIView.animate(withDuration: 0.25) {
                    self.alertView.center = targetView.center
                }
            }
        }
    }
    
    @objc  func dissmissAlert() {
        guard let targetView = myTargetView else {
            return
        }
        
        UIView.animate(withDuration: 0.25, animations: {
            self.alertView.frame = CGRect(
                x: 40, y: targetView.frame.size.height, width: targetView.frame.size.width-80, height: 300
                
            )}, completion: {done in
                if done {
                    UIView.animate(withDuration: 0.25, animations: {
                        self.backgroundView.alpha = 0
                    }, completion: {done in
                        if done {
                            self.alertView.removeFromSuperview()
                            self.backgroundView.removeFromSuperview()
                        }
                        
                    })
                }
                
            }
        )
    }
}