我有UITableView
个用户列表。点击一行时,用户的uid将传递到UIViewController
详细信息视图。 URLRequest
用于检索用户的JSON
数据(用户名,头像等)。但是,详细视图不一致地更新信息。有时它会显示用户的姓名,头像等,但有时候它会显示任何内容,或者它只显示用户名或只显示头像等。
在fetchUser()
方法中,我有一个print("Username: \(self.user.username)")
,显示正在100%的时间内检索到正确的数据,但它不会在视图中100%显示。< / p>
非常感谢任何帮助。
谢谢!
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()
}
答案 0 :(得分:1)
两个建议:
UIView
对象的所有访问都应该在主线程上。您已调度到主线程以致电reloadView
,但也可能在您设置&#34;用户名&#34;和#34;净资产&#34;标签上的值答案 1 :(得分:1)
首先,在viewWillAppear
中调用fetch用户,如下所示:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
fetchUser()
}
然后,像我一样更改代码,不要使用您拥有的reloadView
函数,而是更新fetchUser
函数末尾主线程上的UI元素。我也改了它,所以你没有更新UI两次,因为你在if let uid = ...
fetchUser
语句底部有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()