CustomAlert Message overWrite

56 Views Asked by At

my model :

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

and I create custom alert messages model:

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()
                        }
                        
                    })
                }
                
            }
        )
    }
}

and I have 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()
}

the problem here is the first message is normal but the second message overwrites the other. enter image description here

how can I overcome this problem. I think this is from the inheritance property of the Classes. but I wanted to do my CustomAlert model with Struct because @objc can be only classes

1

There are 1 best solutions below

2
vadian On

The problem is that you don't remove the labels and the button from alertView but add new ones on the next call.

My suggestion is to assign tags to the views and create them only the first time

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()
                        }
                        
                    })
                }
                
            }
        )
    }
}