Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 是否有一个通用且可靠的解决方案,使UICollectionViewCell';什么是宽度包裹内容?_Ios_Swift - Fatal编程技术网

Ios 是否有一个通用且可靠的解决方案,使UICollectionViewCell';什么是宽度包裹内容?

Ios 是否有一个通用且可靠的解决方案,使UICollectionViewCell';什么是宽度包裹内容?,ios,swift,Ios,Swift,我发现制作水平滚动的UICollectionViewCell,以在其内容上实现内容包装功能非常困难,而且容易出错 例如,我有一个UICollectionViewCell,它唯一的内容是UILabel。我需要使用以下代码,以确保其宽度将根据UILabel的长度调整大小 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeFor

我发现制作水平滚动的
UICollectionViewCell
,以在其内容上实现内容包装功能非常困难,而且容易出错

例如,我有一个
UICollectionViewCell
,它唯一的内容是
UILabel
。我需要使用以下代码,以确保其宽度将根据
UILabel
的长度调整大小

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    
    if isSizeToFitCellsNeeded {
        
        // Use 500 (Any arbitary large value will do)
        let sizeee = CGSize.init(width: 500, height: self.frame.height)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        
        let str = dataArray[indexPath.item].name
        
        // Currently, our UILabel is using font UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.medium)
        // I am not sure why do I need to use UIFont.systemFont(ofSize: 23, weight: UIFont.Weight.medium)
        // in cell wrap size calculation, to make thing looks good???
        let font = UIFont.systemFont(ofSize: 23, weight: UIFont.Weight.medium)
        
        let estimatedRect = NSString.init(string: str).boundingRect(with: sizeee, options: options, attributes: [NSAttributedStringKey.font : font], context: nil)
    
        // 44 is minimum touchable area based on Apple design guideline
        return CGSize.init(
            width: max(44, estimatedRect.size.width),
            height: self.frame.height)

    }
    
    return CGSize.init(width: (self.frame.width)/CGFloat(dataArray.count), height: self.frame.height)
}
结果是这样的

尽管它看起来“有效”,但代码并不可靠,也不通用,正如

  • 使用了很多神奇的数字
  • 如果
    UICollectionViewCell
    不再包含单个
    UILabel
    ,而是包含多个不同的UI组件,该怎么办

  • 如果我将
    UILabel
    替换为
    UIImageView
    。突然,密码会被破解。单元格宽度不再按其内容大小换行。我们希望所有单元格大小都相同,因为它们显示的是相同的图标


    我想知道,是否有一个通用且可靠的解决方案,可以使UICollectionViewCell的width wrap内容?

    为了可重用性,您可以注册不同的单元格来对应不同的UI元素组合。然后根据单元格类型,可能会返回不同的大小。例如,UIImageView图标大小固定,标签大小不同等

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        let item = dataArray[indexPath.item]
    
        if item.type == .label { 
            return labelSize
        } else if item.type == .icon { 
            return iconSize    
        }
    
        return defaultSize
    }
    
    为了计算标签大小,我建议通过扩展
    UILabel
    并覆盖其
    intrinsicContentSize
    属性来创建自定义标签。对于不考虑字体大小的填充,定义插入并计算新大小似乎很好。然后,在创建单元格时不需要计算标签,而是在创建标签时定义标签

    override var intrinsicContentSize: CGSize {
        let size = super.intrinsicContentSize
        return CGSize(width: size.width + leftPadding + rightPadding,
            height: size.height + topPadding + bottomPadding)
    }
    

    在这里使用水平堆栈怎么样?在这种情况下,我更喜欢使用堆栈视图。无论您使用什么UI元素(以及隐藏其他元素),堆栈都会调整其大小,您可以根据堆栈视图宽度排列单元格。使用水平堆栈可能不适合我们的情况。正如,我们的标签数量可以任意大。通过使用水平集合视图,我们可以利用它的单元重用功能,消除创建大量UI元素的需要。如果,单元格可能不包含单个标签或单个图标。它可能包含多个标签和多个图标?我明白了,现在我无法找到您需要的抽象级别。如果我能提出新的想法,我会考虑更多并更新答案。如果你能分享你的解决方案,我会很高兴的。祝你好运