簡體   English   中英

如何以編程方式使水平 CollectionView 大小適合其內容

[英]How to make horizontal CollectionView size fit its content programatically

我有一個集合視圖,它占據了整個屏幕並且應該水平滾動。

問題是我無法在保留輪播效果的同時調整項目的大小。 如果我降低項目的大小,單元格垂直堆疊,就像這里一樣:

在此處輸入圖像描述

粉紅色的背景是collectionView。 collectionView 填充 viewController 的視圖,這就是單元格不水平對齊的原因。

alignment 應該是這樣的,它像旋轉木馬一樣水平滾動,但問題是它太大了,它占據了整個視圖。

在此處輸入圖像描述

預計單元格和集合視圖的高度僅為 100 或 200 左右,並且仍然可以水平滾動。

這是我現有的代碼:

我正在使用 SnapKit 進行約束。

視圖控制器

import UIKit
import SnapKit

class ViewController: UIViewController {
    
    
    let viewModel: [SeatViewModel] = [.init(text: "single text"), .init(text: "slightly longer text."), .init(text: "very very very very long long text")]
    
    private lazy var collectionView: UICollectionView = {
      let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
      let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
      cv.delegate = self
      cv.backgroundColor = .white
      cv.register(SeatCardCell.self, forCellWithReuseIdentifier: "SeatCardCell")
      return cv
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(collectionView)
        
        collectionView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.equalTo(200)
            make.height.equalTo(100)
        }
        collectionView.dataSource = self
        collectionView.backgroundColor = .systemPink
    }
    

    
    func lines(label: UILabel) -> Int {
        self.collectionView.layoutIfNeeded()
        let textSize = CGSize(width: label.frame.size.width, height: CGFloat(Float.infinity))
        let rHeight = lroundf(Float(label.sizeThatFits(textSize).height))
        let charSize = lroundf(Float(label.font.lineHeight))
        let lineCount = rHeight/charSize
        return lineCount
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        collectionView.frame = view.bounds
    }
    
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let collectioCell = collectionView.dequeueReusableCell(withReuseIdentifier: "SeatCardCell", for: indexPath) as? SeatCardCell else { fatalError() }
        collectioCell.backgroundColor = [UIColor.green, .red, .black, .brown, .yellow].randomElement()
        collectioCell.viewModel = viewModel[indexPath.row]
        return collectioCell
    }
    
}


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

            return CGSize(width: 200, height: self.collectionView.frame.height)
        }

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

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

查看 Model 和單元格

import UIKit
import SnapKit

struct SeatViewModel {
    let text: String
}

class SeatCardCell: UICollectionViewCell {
    
    var viewModel: SeatViewModel? {
        didSet {
            configure()
        }
    }

    // MARK: - Properties

    let seatImageView = UIImageView(image: nil)
    
    let seatLabel: CustomLabel = {
        let label = CustomLabel()
        return label
    }()

    // MARK: - Lifecycle

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

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

    
    private func configure() {
        guard let viewModel = viewModel else { return }
        seatLabel.text = viewModel.text
        seatLabel.backgroundColor = .cyan
        seatLabel.sizeToFit()
        seatImageView.image = .strokedCheckmark
        
        let stackView = UIStackView(arrangedSubviews: [seatImageView, seatLabel])
        stackView.spacing = 0
        stackView.alignment = .center
        
        addSubview(stackView)
        
        seatImageView.snp.makeConstraints { make in
            make.size.equalTo(40)
        }
        
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
}


// MARK: - CUSTOM TITLE LABEL
class CustomLabel: UILabel {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        self.textColor = .darkGray
        self.textAlignment = .left
        self.numberOfLines = 4
    }
}

您的代碼的問題是您再次將集合視圖框架設置為等於 viewDidLayoutSubviews 中的視圖框架。

您只需要刪除它,您的代碼就可以正常工作。

override func viewDidLayoutSubviews() {
     super.viewDidLayoutSubviews()
     // remove it
     //collectionView.frame = view.bounds
}

最后結果

暫無
暫無

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

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