簡體   English   中英

在水平滾動中使用不同寬度的單元格設置collectionView的大小

[英]Set the size of a collectionView with cell of different width, in a horizontal scrolling

我試圖將一個UICollectionView設置為一個水平菜單,位於另一個UICollectionView上(但這無關緊要)。

現在我的單元格基本上由標簽組成,正如您可以想象的那樣,它們具有不同的寬度。 所以我試圖用這個函數來計算大小:

func getSizeOfCell(string: String, font: UIFont) -> CGSize {
    let textString = string as NSString
    let textAttributes = [NSFontAttributeName: font]
    let size = textString.boundingRect(with: CGSize(width: 320, height: 2000), options: .usesLineFragmentOrigin, attributes: textAttributes, context: nil)
    return CGSize(width: size.width, height: size.height)
}

如您所見,這確實做得不好。 在此處輸入圖片說明

字符串較長時,包含標簽的視圖太大。

我有點被迫給CGSize提供sizeForItemAt嗎? 我不能只是要求我的CollectionView根據包含的標簽自動獲取單元格的大小?

[編輯]這是我的細胞班級:

class MenuCell: UICollectionViewCell {
override init(frame: CGRect) {
    super.init(frame: frame)

    setupViews()
}

override var isSelected: Bool {
    didSet {
        labelTitre.textColor = isSelected ? UIColor.black : .lightGray
    }
}

let labelTitre : UILabel = {
    let label = UILabel()
    label.textColor = .gray
    return label
}()

func setupViews() {
    backgroundColor = UIColor.white
    addSubview(labelTitre)
    addConstraintsWithFormat(format: "H:[v0]", views: labelTitre)
    addConstraintsWithFormat(format: "V:[v0]", views: labelTitre)
    addConstraint(NSLayoutConstraint(item: labelTitre, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
    addConstraint(NSLayoutConstraint(item: labelTitre, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))

}



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

這就是我構造我的collectionView的方法:

lazy var customCollectionView : UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    layout.minimumLineSpacing = 0
    layout.minimumInteritemSpacing = 0
    layout.estimatedItemSize = CGSize(width: 60, height: 30)
    let cv  = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.collectionViewLayout = layout
    cv.backgroundColor = UIColor.white
    cv.dataSource = self
    cv.delegate = self
    return cv

}()

也可以在我的viewController的viewDidLoad()中使用:

    customCollectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellId)
    addSubview(customCollectionView)
    addConstraintsWithFormat(format: "V:|[v0]|", views: customCollectionView)
    addConstraintsWithFormat(format: "H:|[v0]|", views: customCollectionView)

您可以使用約束條件使單元格“自動調整大小”,而無需手動計算文本/標簽大小。

試試看。 當然,將需要對其進行修改以適合您的需求,但是應該給您一些有用的東西( 編輯 :我更新了我的代碼以更接近於您的方法):

//
//  MenuBarViewController.swift
//

import UIKit

private let reuseIdentifier = "MyASCell"

class MyMenuCell: UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)

        setupViews()
    }

    override var isSelected: Bool {
        didSet {
            labelTitre.textColor = isSelected ? UIColor.black : .lightGray
        }
    }

    let labelTitre : UILabel = {
        let label = UILabel()
        label.textColor = .gray
        return label
    }()

    func setupViews() {
        backgroundColor = UIColor.white
        addSubview(labelTitre)

        labelTitre.translatesAutoresizingMaskIntoConstraints = false

        // set constraints to use the label's intrinsic size for auto-sizing
        // we'll use 10 pts for left and right padding
        labelTitre.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10.0).isActive = true
        labelTitre.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10.0).isActive = true

        // center the label vertically (padding controlled by collectionView's layout estimated size
        labelTitre.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

    }

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

}

class MyMenuBarViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    var theLabels = [
        "Intro",
        "Aborigenes",
        "Faune",
        "Flore",
        "Randonnées",
        "A longer label here",
        "End"
    ]

    lazy var theCollectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 1.0
        layout.minimumInteritemSpacing = 1.0
        // note: since the labels are "auto-width-stretching", the height here defines the actual height of the cells
        layout.estimatedItemSize = CGSize(width: 60, height: 28)
        let cv  = UICollectionView(frame: .zero, collectionViewLayout: layout)
        // using lightGray for the background "fills in" the spacing, giving us "cell borders"
        cv.backgroundColor = UIColor.lightGray
        cv.dataSource = self
        cv.delegate = self
        return cv

    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .yellow

        // register the cell
        //      theCollectionView.register(MyASCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        theCollectionView.register(MyMenuCell.self, forCellWithReuseIdentifier: reuseIdentifier)

        // we're going to add constraints, so don't use AutoresizingMask
        theCollectionView.translatesAutoresizingMaskIntoConstraints = false

        // add the "menu bar" to the view
        self.view.addSubview(theCollectionView)

        // pin collection view to left and right edges
        theCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        theCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

        // pin top of collection view to topLayoutGuide
        theCollectionView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true

        // set height of collection view to 30
        theCollectionView.heightAnchor.constraint(equalToConstant: 30.0).isActive = true


        // for demonstration's sake, just add a blue view below the "menu bar"
        let v = UIView(frame: CGRect.zero)
        v.backgroundColor = UIColor.blue
        v.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(v)

        // pin gray view to left, right, bottom of view
        v.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        v.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        v.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

        // pin top of gray view to bottom of collection view
        v.topAnchor.constraint(equalTo: theCollectionView.bottomAnchor).isActive = true

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        // we want a 1-pt border on top, bottom and left and right edges of the collection view itself
        return UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! MyMenuCell

        cell.labelTitre.text = theLabels[indexPath.row]

        // just simulating selection here...
        cell.isSelected = indexPath.row == 0

        return cell
    }

}

編輯:

這是我的代碼結果的上限:

在此處輸入圖片說明

以及代碼的結果上限-修改了一行:

在此處輸入圖片說明

在您的單元格代碼中,更改:

addConstraintsWithFormat(format: "H:[v0]", views: labelTitre)

至:

addConstraintsWithFormat(format: "H:|-10-[v0]-10-|", views: labelTitre)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM