根据是否有图像更改 TableViewCell 的高度
Change the height of a TableViewCell depending on if it has an image
我有一个表格视图,其中表格视图单元格填充了应用程序上的 post 用户。用户可以让 post 只包含文本,也可以在文本中包含图像。
我遇到的问题是根据 post 是否包含图像来设置单元格高度。例如,如果 post 包含一个图像,我希望单元格高度 = 400,但如果它只包含文本,那么我希望单元格高度 = 150。
目前我使用此代码将高度固定为 400,但我不知道如何进行上述修改。
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//auto cell height
return 400
}
post 模型看起来像这样...
class Posts {
var id: String
var author: String
var text: String
var createdAt: Date
var degree: String
var university: String
var uid: String
var photoURL: String
var url: URL
var postID: String
var likes: Int
init(id:String, author:String, text:String, timestamp:Double, degree:String, university:String, uid:String, photoURL:String, url:URL, postID:String, likes:Int) {
self.id = id
self.author = author
self.text = text
self.createdAt = Date(timeIntervalSince1970: timestamp / 1000)
self.degree = degree
self.university = university
self.uid = uid
self.photoURL = photoURL
self.url = url
self.postID = postID
self.likes = likes
}
}
一个相当简单的方法是创建自定义视图单元格并在需要时隐藏 imageView。
创建自定义 tableView 单元格并确保添加 .xib 文件以便能够直观地编辑所有内容:
将行高设置为自动,以便 tableView 知道将高度设置为您需要的任何高度。
然后,您可以将文本和图像视图添加到此自定义单元格中。我之前使用的方法是将两个元素都添加到 stackView 中并对其设置约束。
确保为 stackView 内部的 label 和 imageView 的高度以及从 stackView 到 superView 的底部和顶部的距离设置了约束。这让自动布局知道单元格的高度
现在,任何时候隐藏 imageView(当您没有要显示的图像时)单元格都应该自动调整为更小。
我最终将此代码添加到 tableview cellforrowat 索引路径函数中,以便正确渲染图像。
let imageIndex = posts[indexPath.row].mediaURL
let url = NSURL(string: imageIndex)! as URL
if let imageData: NSData = NSData(contentsOf: url) {
let image = UIImage(data: imageData as Data)
let newWidth = cell.MediaPhoto.frame.width
let scale = newWidth/image!.size.width
let newHeight = image!.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
image!.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
cell.MediaPhoto.image = newImage
cell.MediaPhoto.contentMode = .scaleToFill
cell.MediaPhoto.clipsToBounds = true
我有一个表格视图,其中表格视图单元格填充了应用程序上的 post 用户。用户可以让 post 只包含文本,也可以在文本中包含图像。
我遇到的问题是根据 post 是否包含图像来设置单元格高度。例如,如果 post 包含一个图像,我希望单元格高度 = 400,但如果它只包含文本,那么我希望单元格高度 = 150。
目前我使用此代码将高度固定为 400,但我不知道如何进行上述修改。
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//auto cell height
return 400
}
post 模型看起来像这样...
class Posts {
var id: String
var author: String
var text: String
var createdAt: Date
var degree: String
var university: String
var uid: String
var photoURL: String
var url: URL
var postID: String
var likes: Int
init(id:String, author:String, text:String, timestamp:Double, degree:String, university:String, uid:String, photoURL:String, url:URL, postID:String, likes:Int) {
self.id = id
self.author = author
self.text = text
self.createdAt = Date(timeIntervalSince1970: timestamp / 1000)
self.degree = degree
self.university = university
self.uid = uid
self.photoURL = photoURL
self.url = url
self.postID = postID
self.likes = likes
}
}
一个相当简单的方法是创建自定义视图单元格并在需要时隐藏 imageView。
创建自定义 tableView 单元格并确保添加 .xib 文件以便能够直观地编辑所有内容:
将行高设置为自动,以便 tableView 知道将高度设置为您需要的任何高度。
然后,您可以将文本和图像视图添加到此自定义单元格中。我之前使用的方法是将两个元素都添加到 stackView 中并对其设置约束。
确保为 stackView 内部的 label 和 imageView 的高度以及从 stackView 到 superView 的底部和顶部的距离设置了约束。这让自动布局知道单元格的高度
现在,任何时候隐藏 imageView(当您没有要显示的图像时)单元格都应该自动调整为更小。
我最终将此代码添加到 tableview cellforrowat 索引路径函数中,以便正确渲染图像。
let imageIndex = posts[indexPath.row].mediaURL
let url = NSURL(string: imageIndex)! as URL
if let imageData: NSData = NSData(contentsOf: url) {
let image = UIImage(data: imageData as Data)
let newWidth = cell.MediaPhoto.frame.width
let scale = newWidth/image!.size.width
let newHeight = image!.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
image!.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
cell.MediaPhoto.image = newImage
cell.MediaPhoto.contentMode = .scaleToFill
cell.MediaPhoto.clipsToBounds = true