首页 > 解决方案 > 调整 UICollectionView UICollectionReusableView (header) 宽度

问题描述

我想调整 iPad 中的 collectionview 标题宽度。

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
                        referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: 668, height: 44.0)    
}


public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 50, bottom: 0, right: 50)
}

即使它基于 collectionView 宽度显示 headerView,我也明确设置了宽度。

当前行为:

在此处输入图像描述

预期的: 在此处输入图像描述

标签: iosswiftuicollectionviewuicollectionviewflowlayout

解决方案


这是执行此操作的示例代码:

声明您的集合视图、注册单元格、注册标题并设置约束:

class ViewController: UIViewController {

var collectionview: UICollectionView!
var cellId = "Cell"
let headerId = "myFooterView"
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

var myUIViewArr = ["1", "2", "3", "4", "5", "6", "7"]

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .black
    
    layout.scrollDirection = .vertical
    
    collectionview = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
    collectionview.dataSource = self
    collectionview.delegate = self
    collectionview.register(MenuCell.self, forCellWithReuseIdentifier: cellId)
    collectionview.showsVerticalScrollIndicator = false
    collectionview.backgroundColor = .black
    collectionview.register(MyHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerId)
    collectionview.translatesAutoresizingMaskIntoConstraints = false
    
    view.addSubview(collectionview)
    collectionview.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    collectionview.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
    collectionview.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
    collectionview.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
    
 }
}

现在设置 collectionView 委托和数据源方法:

extension ViewController : UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return myUIViewArr.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    let cell = collectionview.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell
    cell.contentView.backgroundColor = .red
    
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    layout.scrollDirection = .vertical

    let cellInRow = 3
    let totalSpace = layout.sectionInset.left + layout.sectionInset.right + (layout.minimumInteritemSpacing * CGFloat(cellInRow - 1))
    let mySize = collectionView.bounds.width - totalSpace
    let size = mySize / CGFloat(cellInRow)

    return CGSize(width: size, height: size)
}

//set header view height
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: view.frame.width, height: 44)
}

//set header view
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    let view = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerId, for: indexPath) as! MyHeaderView
    
    return view
 }
}

设置标题类:

class MyHeaderView: UICollectionReusableView {

let labelHeader = UILabel()

let imageV: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(systemName: "arrow.right.circle.fill")
    iv.contentMode = .scaleAspectFill
    
    return iv
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    
    backgroundColor = .white
    
    labelHeader.text = "Add Your Text here"
    labelHeader.textColor = .black
    labelHeader.numberOfLines = 0
    labelHeader.backgroundColor = .white
    labelHeader.translatesAutoresizingMaskIntoConstraints = false
    
    imageV.tintColor = .orange
    imageV.translatesAutoresizingMaskIntoConstraints = false
    
    addSubview(imageV)
    imageV.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10).isActive = true
    imageV.heightAnchor.constraint(equalToConstant: 30).isActive = true
    imageV.widthAnchor.constraint(equalToConstant: 30).isActive = true
    imageV.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    addSubview(labelHeader)
    labelHeader.topAnchor.constraint(equalTo: topAnchor).isActive = true
    labelHeader.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
    labelHeader.trailingAnchor.constraint(equalTo: imageV.leadingAnchor).isActive = true
    labelHeader.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
 }
}

和你的细胞类:

class MenuCell: UICollectionViewCell {

let containerView = UIView()
let myView = UIView()

override init(frame: CGRect) {
    super.init(frame: frame)
    
    myView.translatesAutoresizingMaskIntoConstraints = false
    
    contentView.backgroundColor = .clear
    containerView.backgroundColor = .clear
    containerView.translatesAutoresizingMaskIntoConstraints = false
    
    contentView.addSubview(containerView)
    containerView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
    containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
    containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    
    containerView.addSubview(myView)
    myView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
    myView.heightAnchor.constraint(equalToConstant: 60).isActive = true
    myView.widthAnchor.constraint(equalToConstant: 60).isActive = true
    myView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
 }
}  

这是结果:

在此处输入图像描述

如果您想在 MyHeaderView 的标题标签左侧添加一些填充,只需添加前导约束常量,如下所示:

labelHeader.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true

这是结果:

在此处输入图像描述


推荐阅读