Пользовательский интерфейс не получает обновления, хотя использует основной поток - PullRequest
0 голосов
/ 03 марта 2019

Я использую Xcode и Swift.У меня есть класс для UIViewController, который я использую.На этом UIViewController я хочу представить что-то вроде всплывающего окна с моим пользовательским классом ConnectionLostView.На этом UIView есть UIButton.Если вы нажимаете кнопку, вызывается функция tryToReconnect() (которая работает).Эта функция обрабатывает онлайн-данные (что тоже работает) и должна обновлять мой пользовательский интерфейс, используя DispatchQueue.main.async { //updating UI }, но мой пользовательский интерфейс не обновляется (или, скорее, я не могу, т.е. удалить свою кнопку из ее суперпредставления, но я могу удалить себя (что именноработает, а что нет, вы можете видеть как комментарий в коде ниже))

Это класс UIViewController, который я использую для представления своего представления.

class vc: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

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

        //setting up the constraints for connectionStatusView
    }
}

Этоэто класс моего 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
    }
}

Как я могу исправить свой код, чтобы пользовательский интерфейс обновлялся, когда я нажимаю reconnectButton?

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Ваш класс будет выглядеть как

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

}
0 голосов
/ 03 марта 2019

На самом деле поток и очередь отправки - красные сельди.Проблема только в том, что self.tryAgainButton является ссылкой на кнопку, которой нет в интерфейсе с самого начала.Это где-то в мысленном пространстве.У него нет супервизии и не видно.Поэтому вы вызываете removeFromSuperview и ничего не происходит.

Вы добавили кнопку в интерфейс (reconnectButton).[Вы сделали это совершенно неправильно, но что не так с тем, как вы это сделали, это тема для другого вопроса!] Но вы никогда не устанавливали self.tryAgainButton на reconnectButton, поэтому они не являются одинаковыми кнопками.У вас есть две кнопки, одна в интерфейсе (reconnectButton) и одна в области мысли (self.tryAgainButton).

...