Home > database >  Swift: How can i avoid view overlapping in this situation
Swift: How can i avoid view overlapping in this situation

Time:09-16

I'm a noob in Swift and XCode and it may be a silly question, but I can't figure it out on my own :(

This is how my LoginViewController looks like. Image1

And I have the following function that triggers when I press the submit button.

@objc func loginButtontapped(){
        
        
        if emailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            passwordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
            
            customAlert.showAlert(with: "Error", message: "Fill in the fields.", on: self)
            
        } else {
        
        let email = emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        let password = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            
            
                
            Auth.auth().signIn(withEmail: email, password: password) { (result, err) in
                    
                if err != nil {
                    
                    self.customAlert.showAlert(with: "Error", message: "Invalid email or password.", on: self)
                    
                }else{
                
                    
                    let homepageVC = HomepageViewController()
                    homepageVC.modalPresentationStyle = .fullScreen
                    let transition = CATransition()
                    transition.duration = 0.3
                    transition.type = CATransitionType.push
                    transition.subtype = CATransitionSubtype.fromLeft
                    transition.timingFunction = CAMediaTimingFunction(name:CAMediaTimingFunctionName.easeInEaseOut)
                    self.view.window!.layer.add(transition, forKey: kCATransition)
                    self.present(homepageVC, animated: false, completion: nil)
                    
                }}}}

Basically it verifies if the TextFields are empty and after that it shows a view with a message.

The first time after I run the project and I click Submit with the empty fields, I get the desired result, as can be seen here. Screenshot here

The problem appears the second time i press the submit button, after i complete the fields with some text as it shows the views overlapped. Screenshot here

What I'm trying to do is to show one "alert" at a time, depending on the situation.

Below is how my CustomAlert is build.

class CustomAlert{
    
    struct Constants {
        
        static let backgroundAlphaTo: CGFloat = 0.6
    }
    
    private let backgroundView: UIView = {
        
        let backgroundView = UIView()
        backgroundView.backgroundColor = .black
        backgroundView.alpha = 0
        return backgroundView
    }()
    
    private let alertView: UIView = {
        
        let alertView = UIView()
        alertView.backgroundColor = UIColor(rgb: 0x363636, alphaVal: 1)
        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: 180)
       
        let titleLabel = UILabel(frame: CGRect(x: 20,
                                               y: 10,
                                               width: alertView.frame.size.width,
                                               height: 40))
        titleLabel.text = title
        titleLabel.textAlignment = .left
        titleLabel.font = UIFont(name: "Roboto-Regular", size: 20)
        titleLabel.textColor = .white
        
        alertView.addSubview(titleLabel)
        
        let messageLabel = UILabel(frame: CGRect(x: 20,
                                          y: 40,
                                          width: alertView.frame.size.width-30,
                                          height: 60))
        
        
        messageLabel.text = message
        messageLabel.font = UIFont(name: "Roboto-Thin", size: 18)
        messageLabel.textColor = .white
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .left
        
        
        alertView.addSubview(messageLabel)
        
        let button = UIButton (frame: CGRect(x: alertView.frame.size.width-130,
                                             y: alertView.frame.size.height-70,
                                             width: (alertView.frame.midX)/2,
                                             height: 50))
        
        button.setTitle("Okay", for: .normal)
        button.applyGradient(colors: [Helper.UIColorFromRGB(0x694BCE).cgColor,Helper.UIColorFromRGB(0x7D3297).cgColor])
        button.addTarget(self, action: #selector(dismissAlert), for: .touchUpInside)
        alertView.addSubview(button)
        
        UIView.animate(withDuration: 0.25, animations: {
                        
                        self.backgroundView.alpha = Constants.backgroundAlphaTo},
                       completion: {done in
                        if done{
                            UIView.animate(withDuration: 0.25, animations: {
                                self.alertView.center = targetView.center
                                           })
                        }
                       })
    }
    
    @objc func dismissAlert(){
        
        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: { [weak self] 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()
                                }
                                
                            })
                        }
                       })
    }
    
    
}

CodePudding user response:

It looks like you're adding a new UILabel each time you call showAlert function. You should add this label as child of alertView and just change it's text.

CodePudding user response:

i managed to fix it by adding in the dismissAlert() func, the following 2 lines of code:

'''

myTitleLabel?.text = "" myMessageLabel?.text = ""

'''

I also made those 2 global.

  • Related