如何匹配水平 collectionView 单元格的宽度与其内容大小
How to match the horizontal collectionView Cell's width on it's content size
我知道一些与此相关的问题,但我之前尝试过,但仍然没有成功。
以下截图是我的问题
我当前的屏幕显示固定的单元格大小,较小的内容显示空白,较大的内容用点覆盖单元格..
我想要如下
它应该与产品类别名称内容的宽度相匹配。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.catCollectionView{
let catCell = collectionView.dequeueReusableCell(withReuseIdentifier: "catCell", for: indexPath)
as! catCell
DispatchQueue.main.async {
catCell.configureCell()
let catCountInt = self.catCountArray[indexPath.row]
catCell.catCountLabel.text = String(catCountInt)
catCell.catNameLabel.text = self.categoryNameArray[indexPath.row]
catCell.catCountLabel.sizeToFit()
catCell.catNameLabel.sizeToFit()
}
return catCell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let catCell = collectionView.dequeueReusableCell(withReuseIdentifier: "catCell", for: indexPath)
as! catCell
catCell.catNameLabel.text = self.categoryNameArray[indexPath.item]
catCell.catNameLabel.sizeToFit()
let labelWidth = catCell.catNameLabel.frame.width + 10
print("frame width: \(labelWidth)")
return CGSize(width: labelWidth, height: 21)
}
}
也许我在这里遗漏了一件简单的事情,但此刻我还不太明白。请帮助我,抱歉我的英语很奇怪。
而不是 dequeuing
另一个 cell
in collectionView(_:layout:sizeForItemAt:)
,您可以使用 size(withAttributes:)
简单地计算 categoryName
的 width
categoryName
,即
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let text = self.categoryNameArray[indexPath.row] {
let cellWidth = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:14.0)]).width + 10.0
return CGSize(width: cellWidth, height: 21.0)
}
在 attributes
中,给 font
你想要 categoryName
的任何东西。
假设您正在使用一个简单的 UICollectionViewCell
子类,并且在故事板中正确设置了约束(标签被固定到其父视图的所有四个边),如下所示:
class CategoryCell: UICollectionViewCell {
@IBOutlet var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
layer.borderWidth = 1
}
}
然后您可以简单地让自动布局确定单元格的大小:
class CollectionViewController: UICollectionViewController {
let categories = [
"All Products",
"Fresh",
"Health & Beauty",
"Beverages",
"Home & life"
]
private var flowLayout: UICollectionViewFlowLayout? {
return collectionViewLayout as? UICollectionViewFlowLayout
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
flowLayout?.sectionInset = .init(top: 15, left: 15, bottom: 15, right: 15)
flowLayout?.sectionInsetReference = .fromSafeArea
flowLayout?.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
DispatchQueue.main.async {
self.flowLayout?.invalidateLayout()
}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return categories.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell", for: indexPath) as! CategoryCell
cell.nameLabel.text = categories[indexPath.row]
return cell
}
}
结果:
我知道一些与此相关的问题,但我之前尝试过,但仍然没有成功。
以下截图是我的问题
我想要如下
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.catCollectionView{
let catCell = collectionView.dequeueReusableCell(withReuseIdentifier: "catCell", for: indexPath)
as! catCell
DispatchQueue.main.async {
catCell.configureCell()
let catCountInt = self.catCountArray[indexPath.row]
catCell.catCountLabel.text = String(catCountInt)
catCell.catNameLabel.text = self.categoryNameArray[indexPath.row]
catCell.catCountLabel.sizeToFit()
catCell.catNameLabel.sizeToFit()
}
return catCell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let catCell = collectionView.dequeueReusableCell(withReuseIdentifier: "catCell", for: indexPath)
as! catCell
catCell.catNameLabel.text = self.categoryNameArray[indexPath.item]
catCell.catNameLabel.sizeToFit()
let labelWidth = catCell.catNameLabel.frame.width + 10
print("frame width: \(labelWidth)")
return CGSize(width: labelWidth, height: 21)
}
}
也许我在这里遗漏了一件简单的事情,但此刻我还不太明白。请帮助我,抱歉我的英语很奇怪。
而不是 dequeuing
另一个 cell
in collectionView(_:layout:sizeForItemAt:)
,您可以使用 size(withAttributes:)
简单地计算 categoryName
的 width
categoryName
,即
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let text = self.categoryNameArray[indexPath.row] {
let cellWidth = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:14.0)]).width + 10.0
return CGSize(width: cellWidth, height: 21.0)
}
在 attributes
中,给 font
你想要 categoryName
的任何东西。
假设您正在使用一个简单的 UICollectionViewCell
子类,并且在故事板中正确设置了约束(标签被固定到其父视图的所有四个边),如下所示:
class CategoryCell: UICollectionViewCell {
@IBOutlet var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
layer.borderWidth = 1
}
}
然后您可以简单地让自动布局确定单元格的大小:
class CollectionViewController: UICollectionViewController {
let categories = [
"All Products",
"Fresh",
"Health & Beauty",
"Beverages",
"Home & life"
]
private var flowLayout: UICollectionViewFlowLayout? {
return collectionViewLayout as? UICollectionViewFlowLayout
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
flowLayout?.sectionInset = .init(top: 15, left: 15, bottom: 15, right: 15)
flowLayout?.sectionInsetReference = .fromSafeArea
flowLayout?.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
DispatchQueue.main.async {
self.flowLayout?.invalidateLayout()
}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return categories.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell", for: indexPath) as! CategoryCell
cell.nameLabel.text = categories[indexPath.row]
return cell
}
}
结果: