swift - 如何根据标签文本快速更改CollectionView单元格宽度
问题描述
我需要根据它的标签文本更改collectionview单元格宽度,如下所示
为此我给了collectionview约束
top, leading, trailing, = 10 height = 80
在单元格中,我在 uiview 中放置了标签,我放置了 uiview,因为我需要给角落半径
和代码
class SearchFilterVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var textArray = ["hbdhwebhj", "behgwfhjewgbkfjbe", "hbhjs", "bdhsbfhegu", "gwdgyqwuguq"]
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 5
self.collectionView.collectionViewLayout = layout
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return textArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchFilterCollectionViewCell", for: indexPath as IndexPath) as! SearchFilterCollectionViewCell
cell.textLabel.text = textArray[indexPath.row]
return cell
}
}
编辑:
o/p
如何解决这个问题,请提供代码帮助
解决方案
collectionView 中的所有项目都采用完全相同的大小,因为您已layout.itemSize
为 collectionView 的流布局指定
消除layout.itemSize = CGSize(width: self.collectionView.frame.size.width / 2, height: 80)
代码中的其他问题:
layout.invalidateLayout()
是不必要的ViewDidLoad
if let layout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
设置minimumInteritemSpacing
并且minimumLineSpacing
是不必要的,在它上面的声明中你已经创建了let layout = UICollectionViewFlowLayout()
为什么不简单地设置minimumInteritemSpacing
和minimumLineSpacing
那里本身?为什么要使用额外的if let
?
简单地写
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 5
self.collectionView.collectionViewLayout = layout
您不需要指定项目大小,集合视图流布局本质上设置为水平,因此默认情况下,每个项目将采用与集合视图高度相同的高度,并且如果单元格内只有一个标签并且设置了自动布局正确约束,标签的内在内容大小将确保单元格获得适当的宽度
无论出于何种原因,如果您决定将标签包装在UIView
上面的逻辑中,只要您正确设置标签的自动布局约束,标签的内在内容大小将设置 containerView 的宽度,进而有助于设置单元格的宽度适当地,
这里单元格的背景颜色为红色,容器视图为橙色,标签没有背景颜色,我在单元格和视图之间添加了前导和尾随间距为 10,标签和容器视图的前导和尾随间距为 5
编辑:
由于 OP 要求容器视图、标签和单元格之间的约束,我正在更新答案以反映相同
清楚地
- - - - - - - - - - - - Cell - - - - - - - - - - - - - - - -
| - - - - - - - - Container View - - - - - - - - |
| | |5 | |
|-10- |-5- Label -5-| -10- |
| | |5 | |
| - - - - - - - - - - - - - - - - - - - - - - - - - |
| |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
如果需要,您可以在单元格和容器之间添加顶部和底部约束,但我保持容器视图垂直居中到单元格
这个怎么运作?
Label 具有从为其设置的文本中获取的固有内容大小,View 确实根据其子视图的大小获取其固有大小,因为您的容器视图中没有子视图,它从标签中获取其大小,并且显然是尺寸标签返回视图将宽度加 10,高度加 10(前导 5、尾随 5、顶部 5 和底部 5)最后单元格从其子视图中获取其大小,因为只有一个子视图(容器视图)它从容器视图中获取宽度对于高度,它从集合视图中获取高度(因为子视图没有提供足够的数据来计算其高度)
如果由于某种原因(可能是因为您有意/无意地设置了一些其他约束,例如在容器视图上添加宽度约束)标签没有正确采用其内在内容大小,则您始终可以在单元格清醒时将标签设置为setContentCompressionResistancePriority
高setContentHuggingPriority
从笔尖
override func awakeFromNib() {
super.awakeFromNib()
self.label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
self.label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
}
尽管在通常情况下不需要这样做,但如果需要这样做以获得正确的内在大小,则必须有一些其他约束阻止标签采用其正确的隐式内在内容大小,如果我处于您的位置,宁愿检查并修复首先它。尽管如此,您提供的有限代码仍无法进一步调试。
编辑2:
没有意识到 OP 正在使用自定义实例UICollectionViewFlowLayout
并且没有将estimatedItemSize
属性设置为automaticSize
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 5
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
self.collectionView.collectionViewLayout = layout
推荐阅读
- python - 附加一个默认字典
- azure - 如何在 Azure 应用程序网关上使用自定义端口创建 Http 侦听器
- flutter - Flutter iOS错误:无效的`Podfile`文件:没有将nil隐式转换为String
- bash - 如何使用带别名的 SSH
- visual-studio - 如何在 Visual Studio 2019 的文件夹项目中从查询搜索中排除 node_modules 文件夹(ctrl+f 不是 ctrl+shift+f)?
- linux - 如何以编程方式从 rrd db 中删除数据源?
- json - 如何返回模型被序列化导致错误字符串大于 maxJsonLength 的视图
- python - 如何在 Python 中实现 OCL(对象约束语言)
- cassandra - 如何在 Cassandra 的另一个 UDT 中嵌套一个 UDT?
- javascript - 在 Qualtrics 中,如何在具有可变 QID 的调查的后期检索答案?