Настройка высоты ячейки CollectionView в зависимости от количества кнопок - PullRequest
2 голосов
/ 09 июля 2019

У меня есть представление коллекции, которое будет иметь UILabel и от 2-5 UIButton с.

Я хочу, чтобы размер ячейки соответствовал количеству кнопок, видимых в соответствии с каждой ячейкой.Я знаю, что каждая кнопка имеет высоту около 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
             // }

        }
    }

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

Ответы [ 3 ]

0 голосов
/ 10 июля 2019

Вот как я решил эту проблему:

Я использовал 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))
}
0 голосов
/ 10 июля 2019

Используйте 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)

}
0 голосов
/ 09 июля 2019

Как насчет этого?Просто возьмите все кнопки внутри массива и затем прокрутите их, чтобы проверить, какие кнопки скрыты, а какие нет.Вы можете использовать .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
}
...