我有一个带有用户列表的UITableView
。当您点击一行时,用户的 uid 会传递到 UIViewController
详细信息 View 。 URLRequest
用于检索用户的 JSON
数据(用户名、头像等)。但是,详细信息 View 不一致地更新信息。有时它会显示用户的姓名、头像等,但有时它不会显示任何内容,或者仅显示用户名或仅显示头像等。
在 fetchUser()
方法中,我有一个 print("Username:\(self.user.username)")
显示正在检索正确的数据100% 的时间,但不会 100% 的时间在 View 中显示。
任何帮助将不胜感激。
谢谢!
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
中调用 fetch user,如下所示:
覆盖 func viewWillAppear(_animated: Bool) {
super.viewWillAppear(动画)
获取用户()
}
然后,像我一样更改这里的代码,不要使用您拥有的 reloadView
函数,而是在 fetchUser< 末尾更新主线程上的 UI 元素
功能。我还更改了它,这样您就不会更新 UI 两次,因为 fetchUser
中的 if let uid = ...
语句底部有 4 行更新了 UI不在主线程中的元素,这就是为什么在我的版本中我删除了这 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()
关于ios - Swift 3/iOS UIView 在检索远程 JSON 数据后不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45361454/