ios - 自定义 UITableViewCell 的动态高度问题
问题描述
我有一个自定义UITableViewCell
的UICollectionView
。
我在其文件UICollectionView
的每一侧都固定了。XIB
在我的一些单元格中,内容可能会下降,但根据我当前的动态高度设置,我只看到顶部。我正在向我的单元格中添加图像,UICollectionView
因此在一个单元格中可能有 20 个,而另一个单元格可能只有 5 个。现在每一行具有相同的高度,而有些应该不同。
需要注意的UICollectionView
是,单元格中的 不会滚动。
这是我在视图控制器中尝试的内容:
// Here is where I am getting the arr data, which is the folders
// that contains images.
func getDataForSections() {
let storageReference = Storage.storage()
let ref = storageReference.reference().child("abc/xyz/")
ref.listAll { (result, error) in
if let error = error {
// ...
}
for prefix in result.prefixes {
self.arr.append(prefix)
}
self.myTableView.reloadData()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = arr[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "collectionCell", for: indexPath) as! collectionCell
cell.getImagesFromData(data: data)
cell.frame = tableView.bounds
cell.layoutIfNeeded()
cell.collectionView.reloadData()
cell.collectionView.heightAnchor.constraint(equalToConstant: cell.collectionView.collectionViewLayout.collectionViewContentSize.height).isActive = true
cell.layoutIfNeeded()
return cell
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
// How Do I get the Custom size here? Or in heightForRowAt?
return 500.0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
/**
@param numberOfCellsInCollectionView the number of cells of your current collectioview
*/
func calculateHeight(numberOfCellsInCollectionView: Int) -> CGFloat {
let imageHeight: CGFloat = 40.0
let spaceBetweenRows: CGFloat = 20.0 /*Change as you please based on the space you put between your cells (if any) */
let rows: CGFloat = CGFloat(calculateRows(numberOfCellsInCollectionView: numberOfCellsInCollectionView))
/**
1) (rows*imageHeight) calculate the total space occupied by the pictures
2) (rows+2) assuming you want to put a little space between the top and the bottom of the collectionview i used +2. If you don't want to remove the +2
3) ((rows+2)*spaceBetweenRows) total space occupied by the spaces.
**/
let height = (rows*imageHeight)+((rows+2)*spaceBetweenRows)
return height
}
//Calculate the rows
func calculateRows(numberOfCellsInCollectionView: Int) -> Int {
let result = numberOfCellsInCollectionView/6 //Dividing the number of cells for the cells for row
let rest = numberOfCellsInCollectionView%6 //Calculating the module
if rest == 0 {
//If the rest is 0 (ie: you divide 18/6), then you get the result of the division (18/6 = 3)
return result
} else {
//If the rest is > 0 (ie: you divide 17/6), then you get the result of the division + 1 (17/6 = 3+1 = 4) so there's space for the last item
return result+1
}
}
这是我在具有集合视图的自定义单元格中尝试的内容:
func getImagesFromData(prefix: String) {
let storageReference = Storage.storage()
let ref = storageReference.reference().child("abc/xyz/\(prefix)")
ref.listAll { (result, error) in
if let error = error {
// ...
}
self.folderImages.removeAll()
for item in result.items {
if !self.folderImages.contains(item) {
self.folderImages.append(item)
}
}
// Here is where I need to store (or retain) the count
// for each section and then calculate the height or pass
// this data back to the View Controller.
// But with Firebase I am not sure how to return this or
// use a completion.
// reload collection data
self.myCollectionView.reloadData()
}
}
extension customCollectionCell: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return folderImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath) as! imageCell
let theImage = folderImages[indexPath.item]
cell.imageView.sd_setImage(with: theImage, placeholderImage: UIImage(named: "blah")) { (image, error, cacheType, ref) in
if error != nil {
cell.imageView.image = UIImage(named: "blah")
}
}
return cell
}
}
另一个例子:
在这里,我没有使用 a UITableView
with the ,而是使用...UICollectionViewCell
UICollectionView
UICollectionViewCell
我还在单元格中使用该方法的变体UIViewController
来获取计数。
在这个例子中,我可以看到返回之前的值。我只需要知道如何在返回中获取该值作为高度。
这是我尝试过的:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let prefix = arr[indexPath.section]
getImageCountFromPrefix(prefix: prefix.name, completion: { (count, success) in
if success {
self.h = self.calculateHeight(numberOfCellsInCollectionView: count)
// self.h has a value!!! How do I get it in the return?
}
})
return CGSize(width: collectionView.bounds.size.width, height: self.h)
}
解决方案
创建一个函数来确定单元格内图片的高度,然后只使用这样的heightForRowAtIndexPath
函数:
private func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
/* Here I'll just assume the height of the picture is 30. You'll have to put here your function and return the dimension. */
return 30.0
}
请注意,您可能希望向返回值添加一个常量值,以使单元格的外观更清晰。我一般加70.0
哦,我不知道图像,但是当你处理文本时,你也必须在cellForRowAt
.
cell.textLabel?.sizeToFit()
cell.textLabel?.numberOfLines = 0
这是计算集合视图高度的方法
/**
@param numberOfCellsInCollectionView the number of cells of your current collectioview
*/
func calculateHeight(numberOfCellsInCollectionView: Int) -> CGFloat{
let imageHeight: CGFloat = 40.0
let spaceBetweenRows: CGFloat = 5.0 /*Change as you please based on the space you put between your cells (if any) */
let rows: CGFloat = CGFloat(calculateRows(numberOfCellsInCollectionView: numberOfCellsInCollectionView))
/**
1) (rows*imageHeight) calculate the total space occupied by the pictures
2) (rows+2) assuming you want to put a little space between the top and the bottom of the collectionview i used +2. If you don't want to remove the +2
3) ((rows+2)*spaceBetweenRows) total space occupied by the spaces.
**/
let height = (rows*imageHeight)+((rows+2)*spaceBetweenRows)
return height
}
//Calculate the rows
func calculateRows(numberOfCellsInCollectionView: Int) -> Int{
let result = numberOfCellsInCollectionView/6 //Dividing the number of cells for the cells for row
let rest = numberOfCellsInCollectionView%6 //Calculating the module
if rest == 0 {
//If the rest is 0 (ie: you divide 18/6), then you get the result of the division (18/6 = 3)
return result
} else {
//If the rest is > 0 (ie: you divide 17/6), then you get the result of the division + 1 (17/6 = 3+1 = 4) so there's space for the last item
return result+1
}
}
推荐阅读
- css - 如何让网格单元占据整个空间?
- rest - Quarkus 1.5.2.Final:quarkus-resteasy 自动 JAXB 编组/解组不起作用
- c++ - 如何使用 C++ 更改小部件中的文本
- reactjs - 为什么在反应原生功能复合组件中未定义子项?
- php - 无法使用 statickidz api google translate-php 进行翻译
- node.js - 如何使用 .populate().exec() 填充多个子数据?
- php - {{ Laravel 表单文本区域数据值
- python - PostgreSQL 唯一索引性能
- python - 从列中的字符串中删除字符
- javascript - 在nodejs的body parser中将extended to true有什么用?