我實作了一個UITableViewCell社交媒體帖子,其中包括用戶名、userImage、文本、媒體(如用戶發布的影像帖子和點贊、評論按鈕等)。這里的媒體是可選的,如果發布了任何影像,我將取消隱藏UIView包含的 imageView并UIImageView根據來自 API 回應的影像的縱橫比調整高度。
這是我的UITableViewCell課程代碼:
class PostsTableViewCell: UITableViewCell {
@IBOutlet weak var ivProfilePic: UIImageView!
@IBOutlet weak var ivPost: UIImageView!
@IBOutlet weak var lblName: UILabel!
@IBOutlet weak var lblPostContent: UILabel!
@IBOutlet weak var viewPost: UIView!
@IBOutlet weak var heighIvPost: NSLayoutConstraint!
var postImage: UIImage? {
didSet {
if let image = postImage {
configureCellWhenPostImageIsAvailable(image: image)
}
viewPost.isHidden = postImage == nil
layoutIfNeeded()
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
viewPost.isHidden = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func prepareForReuse() {
super.prepareForReuse()
viewPost.isHidden = true
heighIvPost.constant = 162 // default height of UIImageView
ivPost.image = nil
}
// To calculate aspect ratio & set heightIvPost constraint value
func configureCellWhenPostImageIsAvailable(image: UIImage) {
let hRatio = image.size.height / image.size.width
let newImageHeight = hRatio * viewPost.bounds.width
heighIvPost.constant = newImageHeight
ivPost.image = image
ivPost.layoutIfNeeded()
}
}
這是我cellForRowAt在主 UIViewController 中的功能:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PostsTableViewCell", for: indexPath) as! PostsTableViewCell
let data = posts[indexPath.row]
if let userImage = data.memberProfilePic {
cell.ivProfilePic.kf.setImage(with: userImage)
}
cell.lblName.text = data.memberName
if let postText = data.postContent {
cell.lblPostContent.isHidden = false
cell.lblPostContent.text = postText
}
if let postImage = data.postImage { // data.postImage contains URL for image and if not nil then unhide viewPost and set Image
cell.viewPost.isHidden = false
cell.ivPost.kf.setImage(with: postImage)
if let image = cell.ivPost.image {
cell.configureCellWhenPostImageIsAvailable(image: image)
cell.layoutIfNeeded()
}
}
return cell
}
這是我的資料模型以防萬一:
class PostEntity: NSObject {
var postContent: String?
var postImage: URL?
var memberName: String?
var memberProfilePic: URL?
override init() {
}
init(jsonData: JSON){
postContent = jsonData["postContent"].stringValue
postImage = jsonData["postImages"].url
memberName = jsonData["member_name"].stringValue
memberProfilePic = jsonData["member_profile"].url
}
}
當我運行此代碼時,我的要求是如果帖子中有任何影像 ie.. data.postImage != nil,它應該以正確的縱橫比顯示影像,但是我得到的是:
- 加載時
UITableView,加載的單元格顯示具有正確縱橫比的影像。 - 當我向下滾動時, UIImageView 不會以正確的縱橫比顯示影像,而是默認顯示影像。
- 當我向上滾動時,我認為由于
prepareForReuse,它再次以正確的縱橫比顯示影像。
我面臨的唯一問題是當向下滾動并創建新單元格時,如果data.postImage != nil.
以下是進一步說明的視頻鏈接: https ://youtube.com/shorts/vcRb4u_KAVM?feature=share
在上面的視頻中你可以看到,一開始所有影像都有完美的縱橫比,但是當我向下滾動并到達機器人和汽車影像時,它們是默認大小,即 162,但是當我向下滾動并向上滾動到它們時,它們得到調整到所需的結果。
我想消除這種行為并根據影像大小獲得正確的縱橫比。
uj5u.com熱心網友回復:
問題是...
當一個表視圖呼叫cellForRowAt時,行高被設定——通常是對單元格內容的約束。如果在單元格顯示后更改高度,則由您通知表格視圖需要重新計算行高。
因此,您可以像這樣向您的單元格類添加一個閉包:
class PostsTableViewCell: UITableViewCell {
// closure
var layoutChange: ((PostsTableViewCell) -> ())?
// the rest of your cell code...
func configureCellWhenPostImageIsAvailable(image: UIImage) {
let hRatio = image.size.height / image.size.width
let newImageHeight = hRatio * viewPost.bounds.width
heighIvPost.constant = newImageHeight
ivPost.image = image
// not needed
//ivPost.layoutIfNeeded()
// use the closure to inform the table view the row height has changed
self.layoutChange?(self)
}
}
然后,在您的控制器中cellForRowAt:
cell.layoutChange = { [weak self] theCell in
guard let self = self,
let cellIndexPath = tableView.indexPath(for: theCell)
else { return }
// you probably want to update something in your data
// maybe:
var data = self.posts[cellIndexPath.row]
data.profilePicDownloaded = true
self.posts[cellIndexPath.row] = data
// tell the table view to re-cacluclate the row heights
self.tableView.performBatchUpdates(nil, completion: nil)
}
return cell
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/525297.html
