Intereting Posts
UIImages / UIButtons ведут себя по-разному, каждая другая временная программа скомпилирована UiimageView адаптирован в uiview In-memory и in-database оценка NSPredicate дают разные результаты Этот класс не является ключевым значением, совместимым с кодировкой при установке значения в NSDictionary Могу ли я начать создавать приложения для iOS, используя только iPad 2 и iPhone? Внутренние элементы Cocoa-Touch: как представление знает его контроллер? Фрагмент Facebook API Метод Objective-C с блоком завершения возвращает значение, которое я хочу использовать в блоке завершения Проблема для наследования UIAlertAction в Swift Как получить видео-путь в Replay Kit? Прототип ячейки таблицы – рабочие точки не работают Нужна помощь с использованием json-framework на iPhone Xcode UI-файлы для проверки коллекции стали несовместимыми на iOS 11 xcode скомпилировать флаги для создания двух приложений Поворот изображения вокруг фиксированной точки

Swift 3 / iOS UIView не обновляется после получения удаленных данных JSON

У меня есть UITableView со списком пользователей. Когда вы нажимаете на строку, uid пользователя передается в подробное представление UIViewController . URLRequest для извлечения данных JSON пользователя (имя пользователя, аватар и т. Д.). Тем не менее, подробный вид неточно обновляет информацию. Иногда он будет показывать имя пользователя, аватар и т. Д., Но в других случаях он ничего не покажет или он будет показывать только имя пользователя или показывать аватар и т. Д.

В fetchUser() меня есть print("Username: \(self.user.username)") которая показывает, что правильные данные извлекаются в 100% случаев, но не будут отображаться в 100% случаев в представлении.

Любая помощь будет принята с благодарностью.

Благодаря!

 class ProfileViewController: UIViewController { @IBOutlet weak var avatarImageView: UIImageView! @IBOutlet weak var usernameLabel: UILabel! @IBOutlet weak var networthLabel: UILabel! var user: User! var uid: Int? override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. fetchUser() } func reloadView() { self.usernameLabel.text = user.username self.networthLabel.text = "$" + NumberFormatter.localizedString(from: Int((user.networth)!)! as NSNumber, number: NumberFormatter.Style.decimal) self.avatarImageView.downloadImage(from: user.avatar!) circularImage(photoImageView: self.avatarImageView) } func fetchUser() { // Post user data to server let myUrl = NSURL(string: "http://localhost/test/profile") let urlRequest = NSMutableURLRequest(url: myUrl! as URL); urlRequest.httpMethod = "POST" let postString = "uid=\(uid!)" urlRequest.httpBody = postString.data(using: String.Encoding.utf8) let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data, response, error) in if (error != nil) { print("error=\(String(describing: error))") return } // end if self.user = User() do { let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String : AnyObject] if let parseJSON = json?["data"] as? [[String : AnyObject]] { for userFromJson in parseJSON { let userData = User() if let uid = userFromJson["uid"] as? String, let username = userFromJson["username"] as? String, let networth = userFromJson["networth"] as? String, let avatar = userFromJson["avatar"] as? String { userData.uid = Int(uid) userData.username = username userData.networth = networth userData.avatar = avatar self.usernameLabel.text = username self.networthLabel.text = networth self.avatarImageView.downloadImage(from: avatar) circularImage(photoImageView: self.avatarImageView) } // end if self.user = userData } // end for } // end if DispatchQueue.main.async { print("Username: \(self.user.username)") self.reloadView() } } catch let error { print(error) } } task.resume() } 

Во-первых, вызовите выборку пользователя в viewWillAppear следующим образом:

override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) fetchUser() }

Затем измените код здесь, как я, не используйте функцию reloadView вы имели, вместо этого обновите элементы пользовательского интерфейса в основном потоке в конце функции fetchUser . Я также изменил его, так что вы не обновляли интерфейс дважды, потому что у вас есть 4 строки в нижней части if let uid = ... statement в fetchUser которые обновили элементы пользовательского интерфейса, которые не были в основном потоке, поэтому в моем версия я удалил эти 4 строки кода. Дайте мне знать, если бы это сработало для вас.

 let task = URLSession.shared.dataTask(with: urlRequest as URLRequest) { (data, response, error) in if (error != nil) { print("error=\(String(describing: error))") return } // end if self.user = User() do { let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String : AnyObject] if let parseJSON = json?["data"] as? [[String : AnyObject]] { for userFromJson in parseJSON { let userData = User() if let uid = userFromJson["uid"] as? String, let username = userFromJson["username"] as? String, let networth = userFromJson["networth"] as? String, let avatar = userFromJson["avatar"] as? String { userData.uid = Int(uid) userData.username = username userData.networth = networth userData.avatar = avatar } // end if self.user = userData } // end for } // end if DispatchQueue.main.async { self.usernameLabel.text = user.username self.networthLabel.text = "$" + NumberFormatter.localizedString(from: Int((user.networth)!)! as NSNumber, number: NumberFormatter.Style.decimal) self.avatarImageView.downloadImage(from: user.avatar!) circularImage(photoImageView: self.avatarImageView) } } catch let error { print(error) } } task.resume() 

Два предложения:

  1. строго говоря , все обращения к объекту UIView должны быть в основном потоке. Вы отправляете основной поток для вызова reloadView , но, вероятно, также должны делать это, когда вы устанавливаете значения «имя пользователя» и «нетто» на ярлыках
  2. вы уверены, что этикетки пусты? Может ли это быть проблемой автозапуска? (Попробуйте установить цвет фона ярлыков на желтый, чтобы убедиться, что они правильного размера. Иногда автозапуск может скручивать представления до нуля, если существуют конфликтующие ограничения)