当存在图像时,为什么我的 tableview 单元格不能正确调整大小?
Why are my tableview cells not properly sizing when an image is present?
我正在设置一个 "newsfeed" 样式的表格视图,并希望我的自定义单元格根据两个因素自动调整大小:
1) 表示的 post 是否包含图像 - 如果不包含,尽管没有 ImageView 并且大小适当
,单元格应该表现得像那里一样
2) 如果 post 确实包含图像,ImageView 应根据图像高度设置其高度(因此,ImageView 没有高度限制)并且单元格应相应地调整大小
在尝试完成此操作时,我的细胞出现了极其不稳定的行为。最初,带有图像的第一个单元格将正确填充。但是,当您滚动浏览时,图像开始调整大小不正确,而其他图像根本不显示。
我的图像正在通过 Google Firebase 异步下载。
我在我的单元格中使用自动布局,并为所有子视图正确设置了顶部、底部、前导和尾随约束。该问题似乎仅限于 ImageView。没有其他元素受到影响。
我试过在 ImageView 上设置高度限制并根据图像是否要显示以编程方式调整它的大小。这似乎没有帮助。
这是我的表视图委托方法:
// Tableview methods
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mPosts!.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 600
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = newsfeed.dequeueReusableCell(withIdentifier: "newsfeedCell") as! NewsfeedCell
let post = mPosts![indexPath.row]
cell.posterNameDisplay.text = post.getPosterName() + " " + (mAccount?.getFamilyName())!
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM dd, yyyy @ hh:mm a"
let dateString = dateFormatter.string(from: post.getTimeStamp())
cell.timestampDisplay.text = dateString
cell.postMessageDisplay.text = post.getPostMessage()
AccountUtils.loadProfilePhoto(ProfileId: post.getPosterId(), ProfilePhoto: cell.profilePhoto)
cell.profilePhoto.layer.borderWidth = 1.0
cell.profilePhoto.layer.masksToBounds = false
cell.profilePhoto.layer.borderColor = UIColor.white.cgColor
cell.profilePhoto.layer.cornerRadius = cell.profilePhoto.frame.size.width / 2
cell.profilePhoto.clipsToBounds = true
PostUtils.loadPostImage(View: cell.postImage, PostId: post.getPostId())
return cell
}
这是我用来在 ImageView 中下载和设置图像的实用方法:
public static func loadPostImage(View postImage: UIImageView, PostId postId: String) {
let storage = Storage.storage()
let storageRef = storage.reference()
let photoRef = storageRef.child("photos/" + Auth.auth().currentUser!.uid + postId + ".jpg")
photoRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if error != nil {
postImage.image = nil
}
else {
let image = UIImage(data: data!)
postImage.image = image
}
}
}
如果您的单元格有多个独特的布局,每个独特的布局都应该有自己的重用标识符(最好是自己的子类)。
创建两个单元格子类 - 一个仅用于文本,第二个用于带有图像的单元格
将您的 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
更改为类似的内容:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let isCellHasImage: Bool = // understand if it will image cell or just text cell
if (isCellHasImage) {
// dequeue and return your image cell
// return cell
}
// dequeue and return your text-only cell
// ...
// return cell
}
我正在设置一个 "newsfeed" 样式的表格视图,并希望我的自定义单元格根据两个因素自动调整大小:
1) 表示的 post 是否包含图像 - 如果不包含,尽管没有 ImageView 并且大小适当
,单元格应该表现得像那里一样2) 如果 post 确实包含图像,ImageView 应根据图像高度设置其高度(因此,ImageView 没有高度限制)并且单元格应相应地调整大小
在尝试完成此操作时,我的细胞出现了极其不稳定的行为。最初,带有图像的第一个单元格将正确填充。但是,当您滚动浏览时,图像开始调整大小不正确,而其他图像根本不显示。
我的图像正在通过 Google Firebase 异步下载。
我在我的单元格中使用自动布局,并为所有子视图正确设置了顶部、底部、前导和尾随约束。该问题似乎仅限于 ImageView。没有其他元素受到影响。
我试过在 ImageView 上设置高度限制并根据图像是否要显示以编程方式调整它的大小。这似乎没有帮助。
这是我的表视图委托方法:
// Tableview methods
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mPosts!.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 600
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = newsfeed.dequeueReusableCell(withIdentifier: "newsfeedCell") as! NewsfeedCell
let post = mPosts![indexPath.row]
cell.posterNameDisplay.text = post.getPosterName() + " " + (mAccount?.getFamilyName())!
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMMM dd, yyyy @ hh:mm a"
let dateString = dateFormatter.string(from: post.getTimeStamp())
cell.timestampDisplay.text = dateString
cell.postMessageDisplay.text = post.getPostMessage()
AccountUtils.loadProfilePhoto(ProfileId: post.getPosterId(), ProfilePhoto: cell.profilePhoto)
cell.profilePhoto.layer.borderWidth = 1.0
cell.profilePhoto.layer.masksToBounds = false
cell.profilePhoto.layer.borderColor = UIColor.white.cgColor
cell.profilePhoto.layer.cornerRadius = cell.profilePhoto.frame.size.width / 2
cell.profilePhoto.clipsToBounds = true
PostUtils.loadPostImage(View: cell.postImage, PostId: post.getPostId())
return cell
}
这是我用来在 ImageView 中下载和设置图像的实用方法:
public static func loadPostImage(View postImage: UIImageView, PostId postId: String) {
let storage = Storage.storage()
let storageRef = storage.reference()
let photoRef = storageRef.child("photos/" + Auth.auth().currentUser!.uid + postId + ".jpg")
photoRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if error != nil {
postImage.image = nil
}
else {
let image = UIImage(data: data!)
postImage.image = image
}
}
}
如果您的单元格有多个独特的布局,每个独特的布局都应该有自己的重用标识符(最好是自己的子类)。
创建两个单元格子类 - 一个仅用于文本,第二个用于带有图像的单元格
将您的 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
更改为类似的内容:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let isCellHasImage: Bool = // understand if it will image cell or just text cell
if (isCellHasImage) {
// dequeue and return your image cell
// return cell
}
// dequeue and return your text-only cell
// ...
// return cell
}