Richard
Richard

Reputation: 83

UILabel reverts to default text on iPhone rotation

This is a slightly odd one which I'm not sure where to start debugging. I have a UILabel on a standard view which I update the text based on certain conditions. From the IB I have set default text that reads 'Loading...' and then the viewDidAppear method updates the text based on the conditions. This works fine, however, if I then rotate my iPhone (or simulator) it reverts the UILabel back to the standard text of 'Loading...'.

What's interesting is that when I view it on an iPad, both simulator and actual device it doesn't change the text back to the default and acts as I would expect.

I have tried detecting an orientation change and resetting the text but that has no effect, it's a bit like the label has become locked to default state.

Happy to provide code if necessary but I'm really not sure what code is relevant as it's a straight forward label and updating it's text.

Thanks

Portrait View

Landscape View

import UIKit

class PredictionViewController: UIViewController {

    var predictionData: Predictions!
    var embeddedVC: PredictionsTableViewController?

    @IBOutlet weak var messageTextBox: UILabel!
    @IBOutlet weak var predictionSubmitButton: UIButton!
    @IBOutlet weak var predictionSubmitButtonHeight: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        //self.messageTextBox.isEditable = false
        NotificationCenter.default.addObserver(self, selector: #selector(settingChanged(notification:)), name: UserDefaults.didChangeNotification, object: nil)
    }

    override func viewDidAppear(_ animated: Bool) {
        let preferences = UserDefaults.standard
        if (preferences.object(forKey: "regID") == nil)
        {
            loadLoginScreen()
        }
        else {
            let sv = UIViewController.displaySpinner(onView: self.view)
            let predictionStatus = preferences.object(forKey: "predictionStatus") as! String

            switch (predictionStatus) {
                case "inplay":
                    setInplay(view: self)
                case "finished":
                    setFinished(view: self)
                case "predict":
                    setPredict(view: self)
                default:
                    self.messageTextBox.text = "Error!"
            }
            if (self.messageTextBox.isHidden) {
                self.messageTextBox.isHidden = false
            }
            UIViewController.removeSpinner(spinner: sv)
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "predictionSegue") {
            if let vc = segue.destination as? PredictionsTableViewController {
                // get a reference to the embedded VC
                self.embeddedVC = vc
            }
        }
    }

    @objc func settingChanged(notification: NSNotification) {
        let preferences = UserDefaults.standard
        let predictionStatus = preferences.object(forKey: "predictionStatus") as! String

        switch (predictionStatus) {
            case "inplay":
                setInplay(view: self)
            case "finished":
                setFinished(view: self)
            case "predict":
                setPredict(view: self)
            default:
                messageTextBox.text = "Error!"
        }
    }

    func setInplay(view: PredictionViewController) {
        view.messageTextBox.text = "In Play!"
        view.predictionSubmitButtonHeight.constant = 0
    }

    func setFinished(view: PredictionViewController) {
        view.messageTextBox.text = "Finished!"
        view.predictionSubmitButtonHeight.constant = 0
    }

    func setPredict(view: PredictionViewController) {
        view.messageTextBox.text = "Predict Now!"
        view.predictionSubmitButton.isEnabled = true
        view.predictionSubmitButton.setTitle("Submit", for: .normal)
        view.predictionSubmitButtonHeight.constant = 58
    }

    @IBAction func predictionSubmitButtonAction(_ sender: UIButton) {
        let preferences = UserDefaults.standard
        let sv = UIViewController.displaySpinner(onView: self.view)
        CheckTime(finished: { isSuccess in

            switch (isSuccess) {
            case "inplay":
                preferences.set("inplay", forKey: "predictionStatus")
                //too late alert
            case "finished":
                preferences.set("finished", forKey: "predictionStatus")
                //too late alert
            case "predict":
                preferences.set("predict", forKey: "predictionStatus")

                if let predictionData = self.embeddedVC?.getPredictionData() {
                    //send back to website
                    let regID = preferences.object(forKey: "regID")
                    let url = URL(string: "[URL]")
                    let session = URLSession.shared

                    let request = NSMutableURLRequest(url: url!)
                    request.httpMethod = "POST"
                    let bodyData = "{}"

                    request.httpBody = bodyData.data(using: String.Encoding.utf8);
                    let task = session.dataTask(with: request as URLRequest, completionHandler: {
                        (data, response, error) in

                        guard let data = data, let _ = response, error == nil else
                        {
                            DispatchQueue.main.async(
                                execute: {
                                    UIViewController.removeSpinner(spinner: sv)
                                    self.displayAlertMessage(message: "response error: \(String(describing: error?.localizedDescription))", type: "error")
                            }
                            )
                            return
                        }

                        do {

                            let decoder = JSONDecoder()
                            let predictionResult = try decoder.decode(ReturnData.self, from: data)

                            DispatchQueue.main.async(
                                execute: {
                                    if (predictionResult.success) {
                                        self.displayAlertMessage(message: predictionResult.message, type: "message", title: "Predictions Received")
                                    }
                                    else {
                                        self.displayAlertMessage(message: "response error: \(String(describing: error?.localizedDescription))", type: "error")
                                    }
                                    UIViewController.removeSpinner(spinner: sv)
                                }
                            )
                        } catch {
                            DispatchQueue.main.async(
                                execute: {
                                    UIViewController.removeSpinner(spinner: sv)
                                    self.displayAlertMessage(message: "response error: \(error)", type: "error")
                            }
                            )
                            return
                        }
                    })

                    task.resume()
                }
            default:
                UIViewController.removeSpinner(spinner: sv)
                self.messageTextBox.text = "Error!"
                preferences.set("error", forKey: "predictionStatus")
            }
            preferences.synchronize()

            if (self.messageTextBox.isHidden) {
                self.messageTextBox.isHidden = false
            }

        })
    }

}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        if UIDevice.current.orientation.isLandscape {
            print("Landscape")
            //imageView.image = UIImage(named: const2)
        } else {
            print("Portrait")
            //imageView.image = UIImage(named: const)
        }
        self.messageTextBox.text = "Error!"
}

Upvotes: 1

Views: 167

Answers (2)

Carlos Henrique
Carlos Henrique

Reputation: 11

I believe that you should take your code off viewDidAppear and put inside viewDidLoad.

If you don't want to use the code in other orientation, you should uncheck for all other orientations and only choose the one you want to be implemented, that will fix your problem, however if you want to works in other orientations, try to do what I said and see if it works.

Even none of what I just said works, try to look around your code if you have a condition to changes the text when transition happens.

One more thing, just a tip, avoid putting too much code inside of a simple action, try to refactoring in other Methods and then call it inside your action.

Upvotes: 1

B.Saravana Kumar
B.Saravana Kumar

Reputation: 1242

Can You use this Delegate method for screen orientation.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in

    }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
        //refresh view once rotation is completed not in will transition as it returns incorrect frame size.Refresh here
        **//---> Set the text for label here.**

    })
    super.viewWillTransition(to: size, with: coordinator)
}

Upvotes: 2

Related Questions