gpt4 book ai didi

ios - 界面生成器中的图像和标签与 TableView 单元格中的数据重叠

转载 作者:行者123 更新时间:2023-11-28 15:15:32 25 4
gpt4 key购买 nike

我是iOS开发初学者,想做一个instagram clone app,在制作instagram clone app的news feed时遇到了问题。

所以我使用 Firebase 来存储图像和数据库。发布图片(将数据上传到 Firebase)后,我想使用从我的 Firebase 上传的数据填充表格 View 。

但是当我运行该应用程序时, Storyboard中的虚拟图像和标签与我放入表格 View 中的下载数据重叠。我下载的数据最终会在我向下滚动后显示。

这是我运行应用程序时的 gif:

http://g.recordit.co/iGIybD9Pur.gif

.gif 中显示了 3 个用户

  1. 用户名( Storyboard中的虚拟人)
  2. 佐科维里
  3. 梅加瓦蒂研究所

从 Firebase 异步下载图像后(加载指示器消失后),我希望 MegawatiRI 会显示在表格顶部,但虚拟图像会先显示,但在我向下滚动并返回顶部后, MegawatiRI 最终会出现。

我相信 MegawatiRI 已成功下载,但我不知道为什么虚拟图像似乎与实际数据重叠。我不希望在我的应用程序运行时显示虚拟对象。

这是原型(prototype)单元格的屏幕截图:

enter image description here

下面是 TableView Controller 的简化代码:

class NewsFeedTableViewController: UITableViewController {


var currentUser : User!
var media = [Media]()



override func viewDidLoad() {
super.viewDidLoad()



tabBarController?.delegate = self


// to set the dynamic height of table view
tableView.estimatedRowHeight = StoryBoard.mediaCellDefaultHeight
tableView.rowHeight = UITableViewAutomaticDimension

// to erase the separator in the table view
tableView.separatorColor = UIColor.clear

}


override func viewWillAppear(_ animated: Bool) {

// check wheter the user has already logged in or not

Auth.auth().addStateDidChangeListener { (auth, user) in

if let user = user {

RealTimeDatabaseReference.users(uid: user.uid).reference().observeSingleEvent(of: .value, with: { (snapshot) in

if let userDict = snapshot.value as? [String:Any] {
self.currentUser = User(dictionary: userDict)
}


})

} else {
// user not logged in
self.performSegue(withIdentifier: StoryBoard.showWelcomeScreen, sender: nil)
}


}

tableView.reloadData()
fetchMedia()



}




func fetchMedia() {

SVProgressHUD.show()

Media.observeNewMedia { (mediaData) in


if !self.media.contains(mediaData) {
self.media.insert(mediaData, at: 0)
self.tableView.reloadData()
SVProgressHUD.dismiss()
}


}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: StoryBoard.mediaCell, for: indexPath) as! MediaTableViewCell


cell.currentUser = currentUser
cell.media = media[indexPath.section]



// to remove table view highlight style
cell.selectionStyle = .none



return cell
}


}

下面是表格 View 单元格的简化代码:

class MediaTableViewCell: UITableViewCell {

var currentUser: User!
var media: Media! {
didSet {

if currentUser != nil {
updateUI()
}

}
}

var cache = SAMCache.shared()



func updateUI () {


// check, if the image has already been downloaded and cached then just used the image, otherwise download from firebase storage


self.mediaImageView.image = nil
let cacheKey = "\(self.media.mediaUID))-postImage"

if let image = cache?.object(forKey: cacheKey) as? UIImage {
mediaImageView.image = image
} else {
media.downloadMediaImage { [weak self] (image, error) in

if error != nil {
print(error!)
}


if let image = image {
self?.mediaImageView.image = image
self?.cache?.setObject(image, forKey: cacheKey)

}


}

}

那么是什么让虚拟图像与我下载的数据重叠?

最佳答案

回答

出现虚拟图像是因为您的 TableView Controller 在您的当前用户在 tableViewController 上正确设置之前开始渲染单元格。

因此,在第一次调用 cellForRowAtIndexPath 时,您的 Controller 中可能有一个 nil currentUser,它被传递给单元格。因此,您的单元格类中的 didSet 属性观察器不会调用 updateUI():

didSet {
if currentUser != nil {
updateUI()
}
}

稍后,您重新加载数据并且当前用户已经设置,所以事情开始按预期工作。

updateUI() 中的这一行应该隐藏您的虚拟图像。但是,updateUI 并不总是像上面解释的那样被调用:

self.mediaImageView.image = nil

我真的不明白 updateUI 需要当前用户不是 nil 的原因。所以你可以在你的 didSet 观察者中消除 nil 测试,并且总是调用 updateUI:

var media: Media! {
didSet {
updateUI()
}

或者,您可以重新安排您的 TableView Controller ,以便在加载数据源之前真正等待当前用户被设置。 viewWillAppear 中与登录相关的代码具有嵌套的完成处理程序来设置当前用户。这些可能是异步执行的..所以你要么必须等待它们完成,要么处理当前用户为零的情况。

Auth.auth etc { 
// completes asynchronously, setting currentUser
}
// Unless you do something to wait, the rest starts IMMEDIATELY
// currentUser is not set yet

tableView.reloadData()
fetchMedia()

其他说明

(1) 我认为当图像下载并插入共享缓存时重新加载单元格(使用 reloadRows)是一种很好的形式。可以引用这个question里面的答案查看从单元启动的异步任务如何使用 NotificationCenter 或委托(delegate)联系 tableViewController。

(2) 我怀疑您的图片下载任务目前正在主线程中运行,这可能不是您想要的。当您修复该问题时,您需要切换回主线程以更新图像(正如您现在所做的那样)或重新加载该行(正如我在上面所建议的那样)。

关于ios - 界面生成器中的图像和标签与 TableView 单元格中的数据重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46930379/

25 4 0