HorizontalCollectionView Ширина и интервал содержимого - PullRequest
0 голосов
/ 07 ноября 2018

enter image description here

Как сделать ширину меток в моем горизонтальном представлении коллекции, чтобы обернуть ширину содержимого метки и обеспечить одинаковое расстояние между ними? В настоящее время ширина ячейки представления коллекции равна 100. Если я увеличу ширину для соответствия другим меткам, более короткие метки будут иметь больший интервал между ними. Любые идеи будут оценены.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Сначала вычислите ширину текста надписи с помощью шрифта, связанного с текстом.

extension String {
    func size(with font: UIFont) -> CGSize {
        let fontAttribute = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttribute)
        return size
    }
}

Возвращает вычисленную ширину вместе с высотой collectionView в collectionView(_, collectionViewLayout:_, sizeForItemAt).

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

    let newWidth = titles[indexPath.row].size(with: labelFont!).width + 10 //Added 10 to make the label visibility very clear
    return CGSize(width: newWidth, height: collectionView.bounds.height)
}

Весь исходный код:

class ViewController: UIViewController {

    @IBOutlet weak var collection: UICollectionView!

    let labelFont = UIFont(name: "Helvetica Neue", size: 18)
    let titles = ["Hi", "Hello", "HorizontalCollectionView", "VerticalCollectionView"]

    override func viewDidLoad() {

        super.viewDidLoad()
        collection.backgroundColor = UIColor(red: 68/255, green: 143/255, blue: 1, alpha: 1)
        collection.register(UINib.init(nibName: "CustomCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CustomCollectionViewCell")
    }
}

extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        return titles.count
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {

        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {

        return 10 // Adjust the inter item space based on the requirement.
    }

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

    let newWidth = titles[indexPath.row].size(with: labelFont!).width + 10 //Added 10 to make the label visibility very clear
    return CGSize(width: newWidth, height: collectionView.bounds.height)
}

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCollectionViewCell", for: indexPath) as! CustomCollectionViewCell
        cell.titleLabel.text = titles[indexPath.row]
        cell.titleLabel.font = labelFont!
        return cell
    }
}

extension String {
    func size(with font: UIFont) -> CGSize {
        let fontAttribute = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttribute)
        return size
    }
}

Другое решение:

ViewController.swift

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {

    @IBOutlet weak var collView: UICollectionView!


    var tasksArray = ["To Do", "SHOPPING","WORK"]
    var selectedIndex = Int()

    override func viewDidLoad() {
        super.viewDidLoad()
        collView.register(UINib.init(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell")
        let layout = collView?.collectionViewLayout as! UICollectionViewFlowLayout
        layout.itemSize = UICollectionViewFlowLayout.automaticSize
        layout.estimatedItemSize = CGSize(width: 170, height: 50)
        // Do any additional setup after loading the view, typically from a nib.
    }
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return tasksArray.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
        cell.lblName.text = tasksArray[indexPath.row]
        if selectedIndex == indexPath.row
        {
            cell.backgroundColor = UIColor.lightGray
        }
        else
        {
            cell.backgroundColor = UIColor.white
        }
        return cell
    }
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedIndex = indexPath.row
        self.collView.reloadData()
    }
}

Cell.swift

class CollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var lblName: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        layer.borderWidth = 1
        layer.cornerRadius = bounds.height / 2
    }

    override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
        setNeedsLayout()
        layoutIfNeeded()
        let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
        var frame = layoutAttributes.frame
        frame.size.width = ceil(size.width)
        layoutAttributes.frame = frame
        return layoutAttributes
    }
}
0 голосов
/ 07 ноября 2018

Вы должны вручную рассчитать ширину каждой ячейки. Чтобы вычислить ширину, вы фактически вычисляете ширину текста, находящегося в этой ячейке.

используйте следующие

 boundingRect(with:options:attributes:context:)

https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrect

для вычисления ширины заданной строки. Таким образом, после вычисления возвращаемого размера ячейка должна обтекать текст.

Теперь перейдем ко второй части, равному интервалу между предметами. используйте interItemSpacing для определения расстояния между каждой ячейкой.

...