简体   繁体   中英

UI is not getting update although using main thread

I am using Xcode and Swift. I have a class for the UIViewController I am using. On this UIViewController I want to present some kind of pop over view with my custom class ConnectionLostView . On this UIView there is an UIButton . If you press the button the tryToReconnect() function is called (which works). This function processes the online data (which works too) and should update my UI using DispatchQueue.main.async { //updating UI } but my UI isn't getting updated (or rather I can't ie remove my button from its superview but I can remove self (what exactly works and what doesn't you can see as comment in the code below))

That is the class of the UIViewController I am using to present my view.

class vc: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let connectionStatusView = ConnectionLostView()
        connectionStatusView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(connectionStatusView)

        //setting up the constraints for connectionStatusView
    }
}

This is the class of my UIView :

class ConnectionLostView: UIView {
    let tryAgainButton = UIButton(type: .roundedRect)

    func tryToReconnect() {
        let url = URL(string: "http://worldclockapi.com/api/json/est/now")!
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        let task = session.dataTask(with: url) { (data, response, error) in
            if error != nil {
                print(error)
            } else {
                do {
                    if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {
                        if let data = json["data"] as? String {
                            // code for processing the data

                            DispatchQueue.main.async {
                                self.removeFromSuperview() //Does work
                                self.tryAgainButton.removeFromSuperview() // does not work
                            }
                        }
                    }
                } catch {
                    print(error)
                }
            }
        }
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        //setting up the button
        let buttonAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18)]
        let attributedButtonString = NSAttributedString(string: "Try To Reconnect", attributes: buttonAttributes)
        let reconnectButton = UIButton(type: .roundedRect)
        reconnectButton.translatesAutoresizingMaskIntoConstraints = false
        reconnectButton.setAttributedTitle(attributedButtonString, for: .normal)
        reconnectButton.addTarget(self, action: #selector(tryToReconnect), for: .touchUpInside)
        addSubview(reconnectButton)

        // setting up constraints for reconnectButton
    }
}

How can I fix my code so the UI is updated when I press the reconnectButton ?

Actually, the thread and the dispatch queue are red herrings. The problem is merely that self.tryAgainButton is a reference to a button that is not in the interface to begin with. It is off in thought-space somewhere. It has no superview and is not visible. Therefore you call removeFromSuperview on it and nothing happens.

You did add a button to the interface ( reconnectButton ). [You did that in a completely wrong way, but what's wrong with the way you did it would be a subject for a different question!] But you never set self.tryAgainButton to reconnectButton , so they are not the same buttons. You have two buttons, the one in the interface ( reconnectButton ) and the one off in thought-space ( self.tryAgainButton ).

Your class would look like

class ConnectionLostView: UIView {

    let reconnectButton = UIButton(type: .roundedRect)

    @objc func tryToReconnect() {

    } 
    override init(frame: CGRect) {
        super.init(frame: frame)

        let buttonAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18)]
        let attributedButtonString = NSAttributedString(string: "Try To Reconnect", attributes: buttonAttributes) 
        reconnectButton.translatesAutoresizingMaskIntoConstraints = false
        reconnectButton.setAttributedTitle(attributedButtonString, for: .normal)
        reconnectButton.addTarget(self, action: #selector(tryToReconnect), for: .touchUpInside)
        addSubview(reconnectButton)

        // add constraints for the button

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM