我有一个带有用户列表的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
函数末尾更新主线程上的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()