英文:
How to fix UICollectionViewCells sometimes not loading in?
问题
我正在尝试在我的应用程序顶部创建一个小的水平UICollectionView,但每次加载应用程序时,总会有2或3个单元格无法加载其内容。而且不加载的单元格在变化。
这是我所做的事情:
public var collectionViewDates = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionViewDates)
collectionViewDates.frame = CGRect(x: 0,
y: 90,
width: view.width,
height: 50)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DatesCollectionViewCell.identifier, for: indexPath) as! DatesCollectionViewCell
cell.dateLabel.text = "I dag\(indexPath.row)"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DatesCollectionViewCell.identifier, for: indexPath) as! DatesCollectionViewCell
return CGSize(width: cell.dateLabel.frame.width + 30, height: collectionView.frame.height)
}
还有在单元格中的部分:
public var dateLabel: UILabel = {
let label = UILabel()
label.text = "I dag"
label.adjustsFontSizeToFitWidth = true
label.font = .systemFont(ofSize: 20, weight: .bold)
label.backgroundColor = .systemBlue
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(dateLabel)
dateLabel.frame = CGRect(x: 0,
y: 0,
width: 50,
height: contentView.frame.height)
dateLabel.center.y = contentView.center.y
dateLabel.center.x = contentView.center.x
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
我不明白为什么有时候单元格会加载,因为我以前使用其他水平UICollectionView也做过这个。但这次我不太幸运。
英文:
I am trying to make a little horizontal UICollectionView in the top section of my app but every time I load the app there are always like 2 or 3 cells that don't load its content. And the cells that don't load are changing.
Here is what I have done:
public var collectionViewDates = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionViewDates)
collectionViewDates.frame = CGRect(x: 0,
y: 90,
width: view.width,
height: 50)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DatesCollectionViewCell.identifier, for: indexPath) as! DatesCollectionViewCell
cell.dateLabel.text = "I dag\(indexPath.row)"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DatesCollectionViewCell.identifier, for: indexPath) as! DatesCollectionViewCell
return CGSizeMake(cell.dateLabel.width + 30, collectionView.height)
}
And in the cell:
public var dateLabel: UILabel = {
let label = UILabel()
label.text = "I dag"
label.adjustsFontSizeToFitWidth = true
label.font = .systemFont(ofSize: 20, weight: .bold)
label.backgroundColor = .systemBlue
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(dateLabel)
dateLabel.frame = CGRect(x: 0,
y: 0,
width: 50,
height: contentView.height)
dateLabel.center.y = contentView.center.y
dateLabel.center.x = contentView.center.x
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
I don't understand why the cells sometimes load because I have done this before with other horizontal UICollectionViews. But this time I was not so lucky.
答案1
得分: 1
以下是翻译好的内容:
首先,花一点时间学习自动布局。
其次,如果您想要 50x50
的单元格,请在集合视图的流布局上设置 .itemSize
。
看一下这个:
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
public var collectionViewDates: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let fl = UICollectionViewFlowLayout()
fl.scrollDirection = .horizontal
fl.minimumLineSpacing = 24.0
fl.minimumInteritemSpacing = 24.0
fl.itemSize = .init(width: 50.0, height: 50.0)
collectionViewDates = UICollectionView(frame: .zero, collectionViewLayout: fl)
collectionViewDates.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionViewDates)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
collectionViewDates.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
collectionViewDates.leadingAnchor.constraint(equalTo: g.leadingAnchor),
collectionViewDates.trailingAnchor.constraint(equalTo: g.trailingAnchor),
collectionViewDates.heightAnchor.constraint(equalToConstant: 64.0),
])
collectionViewDates.register(DatesCollectionViewCell.self, forCellWithReuseIdentifier: DatesCollectionViewCell.identifier)
collectionViewDates.dataSource = self
collectionViewDates.delegate = self
collectionViewDates.backgroundColor = .black
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DatesCollectionViewCell.identifier, for: indexPath) as! DatesCollectionViewCell
cell.dateLabel.text = "I dag\(indexPath.row)"
return cell
}
}
class DatesCollectionViewCell: UICollectionViewCell {
static let identifier: String = "datesCell"
public var dateLabel: UILabel = {
let label = UILabel()
label.text = "I dag"
label.adjustsFontSizeToFitWidth = true
label.font = .systemFont(ofSize: 20, weight: .bold)
label.backgroundColor = .systemBlue
label.textColor = .white
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
dateLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(dateLabel)
NSLayoutConstraint.activate([
dateLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
dateLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
dateLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
dateLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
}
结果:
编辑
如果您希望单元格的大小适应标签的宽度...
给流布局一个估计的项目大小:
//fl.itemSize = .init(width: 50.0, height: 50.0)
fl.estimatedItemSize = .init(width: 50.0, height: 50.0)
并且不要设置标签自动调整字体大小:
//label.adjustsFontSizeToFitWidth = true
英文:
First, spend a little time learning about auto-layout.
Second, if you want 50x50
cells, set the .itemSize
on the collection view's flow layout.
Take a look at this:
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
public var collectionViewDates: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let fl = UICollectionViewFlowLayout()
fl.scrollDirection = .horizontal
fl.minimumLineSpacing = 24.0
fl.minimumInteritemSpacing = 24.0
fl.itemSize = .init(width: 50.0, height: 50.0)
collectionViewDates = UICollectionView(frame: .zero, collectionViewLayout: fl)
collectionViewDates.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionViewDates)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
collectionViewDates.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
collectionViewDates.leadingAnchor.constraint(equalTo: g.leadingAnchor),
collectionViewDates.trailingAnchor.constraint(equalTo: g.trailingAnchor),
collectionViewDates.heightAnchor.constraint(equalToConstant: 64.0),
])
collectionViewDates.register(DatesCollectionViewCell.self, forCellWithReuseIdentifier: DatesCollectionViewCell.identifier)
collectionViewDates.dataSource = self
collectionViewDates.delegate = self
collectionViewDates.backgroundColor = .black
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DatesCollectionViewCell.identifier, for: indexPath) as! DatesCollectionViewCell
cell.dateLabel.text = "I dag\(indexPath.row)"
return cell
}
}
class DatesCollectionViewCell: UICollectionViewCell {
static let identifier: String = "datesCell"
public var dateLabel: UILabel = {
let label = UILabel()
label.text = "I dag"
label.adjustsFontSizeToFitWidth = true
label.font = .systemFont(ofSize: 20, weight: .bold)
label.backgroundColor = .systemBlue
label.textColor = .white
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
dateLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(dateLabel)
NSLayoutConstraint.activate([
dateLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
dateLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
dateLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
dateLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
}
Result:
Edit
If you want the cells to size to fit the widths of the labels...
Give the flow layout an estimated item size:
//fl.itemSize = .init(width: 50.0, height: 50.0)
fl.estimatedItemSize = .init(width: 50.0, height: 50.0)
and don't set the label to autoshrink the font:
//label.adjustsFontSizeToFitWidth = true
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论