简体   繁体   English

尽管使用主线程,UI仍未更新

[英]UI is not getting update although using main thread

I am using Xcode and Swift. 我正在使用Xcode和Swift。 I have a class for the UIViewController I am using. 我有一个正在使用的UIViewController的类。 On this UIViewController I want to present some kind of pop over view with my custom class ConnectionLostView . 在此UIViewController我想用自定义类ConnectionLostView呈现某种弹出视图。 On this UIView there is an UIButton . 在此UIView有一个UIButton If you press the button the tryToReconnect() function is called (which works). 如果按下按钮,将tryToReconnect()函数(有效)。 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)) 此函数处理在线数据(也可以使用),并且应该使用DispatchQueue.main.async { //updating UI }更新我的UI,但是我的UI尚未更新(或者我不能从其超级视图中删除按钮)但我可以删除self(在下面的代码中,什么是正确的,什么是您不能看到的注释)

That is the class of the UIViewController I am using to present my view. 那是我用来呈现我的视图的UIViewController的类。

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 : 这是我的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 ? 如何修复代码,以便在按下reconnectButton时更新UI?

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. 问题仅在于self.tryAgainButton是对不在界面中的按钮的引用。 It is off in thought-space somewhere. 它不在思想空间中的某个地方。 It has no superview and is not visible. 它没有超级视图,因此不可见。 Therefore you call removeFromSuperview on it and nothing happens. 因此,您可以对它调用removeFromSuperview而没有任何反应。

You did add a button to the interface ( reconnectButton ). 您确实向界面添加了一个按钮( 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. [您以完全错误的方式进行了此操作,但是您的操作方式出了什么问题将是另一个问题的主题!]但是您从未将self.tryAgainButton设置为reconnectButton ,因此它们不是相同的按钮。 You have two buttons, the one in the interface ( reconnectButton ) and the one off in thought-space ( self.tryAgainButton ). 您有两个按钮,一个在界面中( reconnectButton ),一个在思想空间中关闭( 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")
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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