我试图在不使用界面构建器的情况下构建集合视图,但我还没有能够调整单元格的宽度。细胞似乎保持在最小的方形尺寸,我希望细胞伸展视图的宽度。
我对约束的错误是什么?
具体做法是:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 50)
}
似乎没有调整单元格的宽度或高度,完整示例:
import UIKit
class UserCollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "foo"
collectionView?.backgroundColor = UIColor.red
collectionView?.alwaysBounceVertical = true
collectionView?.register(UserCell.self, forCellWithReuseIdentifier: "cellId")
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let userCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath)
return userCell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 50)
}
}
class UserCell:UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let nameLabel: UILabel = {
let label = UILabel()
label.text = "foo"
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 14)
return label
}()
func setupView() {
addSubview(nameLabel)
let hConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel])
addConstraints(hConstraints)
}
}
答案 0 :(得分:1)
就约束的错误而言,你错过了纵向约束:
func setupView() {
addSubview(nameLabel)
var constraints: [NSLayoutConstraint] = []
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", metrics: nil, views: ["v0": nameLabel])
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", metrics: nil, views: ["v0": nameLabel])
addConstraints(constraints)
}
但这不是你的细胞大小错误的原因。这是因为您的sizeForItemAt
将不会被调用,因为您尚未声明UICollectionViewDelegateFlowLayout
一致性。设置一个你现在拥有的断点,你会发现它没有被调用。您可以通过将其移动到定义一致性的扩展中来解决此问题:
extension UserCollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.bounds.width, height: 50)
}
}
或者,更好的是,由于它们完全一样,我只需为整个布局设置itemSize
:
override func viewDidLoad() {
super.viewDidLoad()
let layout = collectionView!.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: view.bounds.width, height: 50)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let layout = self.collectionView!.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: size.width, height: 50)
}
答案 1 :(得分:1)
我对约束的错误是什么?
无。 UICollectionViewFlowLayout下的UICollectionViewCell的宽度与其内部约束无关。 (应该有一个功能允许这个,但它从来没有对我有用。)
您可以通过设置流布局的itemSize
或在集合视图的委托中实现collectionView(_:layout:sizeForItemAt:)
来明确设置宽度(通常是UICollectionViewController,并且无论如何必须也正如你在Rob的回答中所说的那样明确地采用了UICollectionViewDelegateFlowLayout。
所以只需改变一下:
class UserCollectionViewController: UICollectionViewController {
到此:
class UserCollectionViewController : UICollectionViewController, UICollectionViewDelegateFlowLayout {
你已经完成了。
答案 2 :(得分:0)
在UIView上创建扩展并添加以下代码:
extension UIView {
func addConstraintsWithformat(format: String, views: UIView...) {
// abstracting contstraints code
var viewsDict = [String: UIView]()
for(index,view) in views.enumerated() {
let key = "v\(index)"
viewsDict[key] = view
view.translatesAutoresizingMaskIntoConstraints = false
}
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDict))
}
}
然后为collectionViewCell
创建自定义类并添加以下代码:
private func setUpContainerView() {
let containerView = UIView()
addSubview(containerView)
addConstraintsWithformat(format: "H:|-90-[v0]|", views: containerView)
addConstraintsWithformat(format: "V:[v0(50)]|", views: containerView)
addConstraint(NSLayoutConstraint(item: containerView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
// set up labels and contents inside the ContainerView and set their constraints with addConstraintsWithformat
}
在override func setUpViews() {}