【问题标题】:Setting CollectionView cell height based on number of buttons根据按钮数量设置 CollectionView 单元格高度
【发布时间】:2019-11-18 14:03:20
【问题描述】:

我有一个集合视图,它将有一个 UILabel 和 2-5 个 UIButtons。

我希望单元格根据每个单元格调整为可见按钮的数量。我知道每个按钮大约有 100 高。

class myViewController: UIViewController {

    var myCollectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let layout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 100, right: 0) // add spacing to the bottom
        layout.itemSize = CGSize(width: self.view.frame.width, height: 300)
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 20
        layout.minimumInteritemSpacing = 20

        myCollectionView=UICollectionView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height), collectionViewLayout: layout)
        myCollectionView.delegate=self
        myCollectionView.dataSource=self
        myCollectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
        myCollectionView.alwaysBounceVertical = false
        myCollectionView.showsVerticalScrollIndicator = false
        myCollectionView.translatesAutoresizingMaskIntoConstraints=false
        myCollectionView.backgroundColor=UIColor.white
        myCollectionView.isPagingEnabled = false

        loadViews()
    }

    func loadViews() {
        self.view.addSubview(myCollectionView)
        myCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive=true
        myCollectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive=true
        myCollectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive=true
        myCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive=true

    }

}

请注意,上面的代码块有 layout.itemSize = CGSize(width: self.view.frame.width, height: 300),它适用于 3 个按钮 (3*100 = 300)。

然后在设置我的单元格类时,我创建我的按钮,然后根据变量(在此底部)确定它们的可见性。


class MyCollectionViewCell: UICollectionViewCell {
    var btn1: UIButton!
    var btn2: UIButton!
    var btn3: UIButton!
    var btn4: UIButton!
    var btn5: UIButton!

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

        setupViews()
    }

    func setupViews() {

        addSubview(lblQue)
        lblQue.topAnchor.constraint(equalTo: self.topAnchor, constant: 30).isActive=true
        lblQue.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 12).isActive=true
        lblQue.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -12).isActive=true
        lblQue.heightAnchor.constraint(equalToConstant: 50).isActive=true

        let btnWidth: CGFloat = 650
        let btnHeight: CGFloat = 65
        btn1 = getButton(tag: 0)
        addSubview(btn1)
        NSLayoutConstraint.activate([btn1.topAnchor.constraint(equalTo: lblQue.bottomAnchor, constant: 10), btn1.leftAnchor.constraint(equalTo: self.centerXAnchor, constant: -300), btn1.widthAnchor.constraint(equalToConstant: btnWidth), btn1.heightAnchor.constraint(equalToConstant: btnHeight)])
        btn1.addTarget(self, action: #selector(btnOptionAction), for: .touchUpInside)

        btn2 = getButton(tag: 1)
        addSubview(btn2)
        NSLayoutConstraint.activate([btn2.topAnchor.constraint(equalTo: btn1.bottomAnchor, constant: 10), btn2.leftAnchor.constraint(equalTo: self.centerXAnchor, constant: -300), btn2.widthAnchor.constraint(equalToConstant: btnWidth), btn2.heightAnchor.constraint(equalToConstant: btnHeight)])
        btn2.addTarget(self, action: #selector(btnOptionAction), for: .touchUpInside)

        btn3 = getButton(tag: 2)
        addSubview(btn3)
        NSLayoutConstraint.activate([btn3.topAnchor.constraint(equalTo: btn2.bottomAnchor, constant: 10), btn3.leftAnchor.constraint(equalTo: self.centerXAnchor, constant: -300), btn3.widthAnchor.constraint(equalToConstant: btnWidth), btn3.heightAnchor.constraint(equalToConstant: btnHeight)])
        btn3.addTarget(self, action: #selector(btnOptionAction), for: .touchUpInside)

        btn4 = getButton(tag: 3)
        addSubview(btn4)
        NSLayoutConstraint.activate([btn4.topAnchor.constraint(equalTo: btn3.bottomAnchor, constant: 10), btn4.leftAnchor.constraint(equalTo: self.centerXAnchor, constant: -300), btn4.widthAnchor.constraint(equalToConstant: btnWidth), btn4.heightAnchor.constraint(equalToConstant: btnHeight)])
        btn4.addTarget(self, action: #selector(btnOptionAction), for: .touchUpInside)

        btn5 = getButton(tag: 4)
        addSubview(btn5)
        NSLayoutConstraint.activate([btn5.topAnchor.constraint(equalTo: btn4.bottomAnchor, constant: 10), btn5.leftAnchor.constraint(equalTo: self.centerXAnchor, constant: -300), btn5.widthAnchor.constraint(equalToConstant: btnWidth), btn5.heightAnchor.constraint(equalToConstant: btnHeight)])
        btn5.addTarget(self, action: #selector(btnOptionAction), for: .touchUpInside)
    }

    func getButton(tag: Int) -> UIButton {
        let btn=UIButton()
        btn.tag=tag
        btn.setTitle("Option", for: .normal)
        btn.setTitleColor(UIColor.black, for: .normal)
        btn.backgroundColor=UIColor.white
        btn.layer.borderWidth=1
        btn.layer.borderColor=UIColor.darkGray.cgColor
        btn.layer.cornerRadius=5
        btn.clipsToBounds=true
        btn.translatesAutoresizingMaskIntoConstraints=false
        return btn
    }

    let lblQue: UILabel = {
        let lbl=UILabel()
        lbl.text="This is a question and you have to answer it?"
        lbl.textColor=UIColor.black
        lbl.textAlignment = .center
        lbl.font = UIFont.systemFont(ofSize: 20)
        lbl.numberOfLines=4
        lbl.translatesAutoresizingMaskIntoConstraints=false
        return lbl
    }()

    var myVariable: MyClassIMade? {
        didSet {
             // go through and determine button Text and Visibility of each button
             // i.e. 
             // if 1>0 { 
             //     btn3.visible = false
             // } else {
             //     btn3.visible = true
             // }

        }
    }

那么如何确定有多少按钮可见,以确定每个部分的单元格大小?

【问题讨论】:

标签: ios swift dynamic uicollectionview


【解决方案1】:

这样的事情怎么样?只需获取数组中的所有按钮,然后遍历它们以检查哪些按钮是隐藏的,哪些不是。你可以使用 .isHidden 隐藏和显示它们,然后检查哪个隐藏并返回数字..

示例函数:

func getButtonsCount(buttons: [UIButton]) -> Int{
    //A counter to get how many button are not hidden
    var count = Int()
    //A Loop to check which buttons are hidden and increment the counter
    for button in buttons {
        if button.isHidden == true {
            count += 1
        }
    }

    return count
}

【讨论】:

  • 没有意义,因为您可以在文件中看到总共 5 个UIButton
  • 嗨@yasser,我该如何设置我的布局呢?我确实在某些按钮上设置了 .isHidden = true。
【解决方案2】:

这是我最终解决的方法:

我使用了sizeForItemAt,它覆盖了所有其他内容,并允许我为每一行/用例获取我的单元格。

基本上,我可以访问绑定到我的单元格的所有控件并确定它们的可见性并据此更改高度。

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

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! QuizCollectionViewCell

    var countOfButtonsNotHidden = 0

    if !cell.btn1.isHidden {
        countOfButtonsNotHidden += 1
    }
    if !cell.btn2.isHidden {
        countOfButtonsNotHidden += 1
    }
    if !cell.btn3.isHidden {
        countOfButtonsNotHidden += 1
    }
    if !cell.btn4.isHidden {
        countOfButtonsNotHidden += 1
    }
    if !cell.btn5.isHidden {
        countOfButtonsNotHidden += 1
    }

    return CGSize(width: self.view.frame.width, height: CGFloat(countOfButtonsNotHidden * 100))
}

【讨论】:

    【解决方案3】:

    使用UIStackView 来布局您的按钮。当您将按钮设置为.isHidden 时,堆栈视图将自动处理按钮的布局。

    例子:

    let stackView = UIStackView(arrangedSubviews: [button1, button2, button3, button4, button5])
    stackView.axis = .vertical
    stackView.alignment = .fill
    stackView.distribution = .equalSpacing
    stackView.spacing = 10
    

    接下来,您可以通过将可见按钮的数量乘以设置的按钮高度来计算集合视图单元格的高度。

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCellIdentifier", for: indexPath) as! YourCellClass
    
        let buttonHeight: CGFloat = 45
        let numberOfVisibleButtons = 0
    
        if !cell.button1.isHidden { numberOfVisibleButtons += 1 }
        if !cell.button2.isHidden { numberOfVisibleButtons += 1 }
        if !cell.button3.isHidden { numberOfVisibleButtons += 1 }
        if !cell.button4.isHidden { numberOfVisibleButtons += 1 }
        if !cell.button5.isHidden { numberOfVisibleButtons += 1 }
    
        let cellHeight: CGFloat = (buttonHeight + cell.stackView.spacing) * numberOfVisibleButtons
    
        return CGSize(width: yourCellWidth, height: cellHeight)
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多