繁体   English   中英

自定义 UITableViewCell 的动态高度问题

[英]Dynamic Height Issue for Custom UITableViewCell

我有一个自定义UITableViewCell ,里面有一个UICollectionView

我将UICollectionView固定在其XIB文件的每一侧。

在我的一些单元格中,内容可能会下降,但根据我当前的动态高度设置,我只看到顶部。 我正在将图像添加到我的UICollectionView中,因此在一个单元格中可能有 20 个,而另一个可能只有 5 个。现在每一行具有相同的高度,而有些应该不同。

需要注意的是,单元格中的UICollectionView不会滚动。

这是我在 View Controller 中尝试的内容:

// 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
    }
}

另一个例子:

在这里,我没有使用带有UITableViewUICollectionViewCell ,而是使用UICollectionViewCell UICollectionView

我还在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)
}

创建一个 function 来确定单元格内图片的高度,然后只使用heightForRowAtIndexPath function ,如下所示:

 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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM