2
votes

Définition de la hauteur de cellule CollectionView en fonction du nombre de boutons

J'ai une vue de collection qui aura un UILabel et entre 2 et 5 UIButton s.

Je veux que la cellule soit dimensionnée en fonction du nombre de boutons visible selon chaque cellule. Je sais que chaque bouton a une hauteur d'environ 100.

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
             // }

        }
    }

Notez que le bloc de code ci-dessus a layout.itemSize = CGSize (width: self.view.frame .width, height: 300) qui fonctionne très bien pour 3 boutons (3 * 100 = 300).

Ensuite, lors de la configuration de ma classe de cellules, je crée mes boutons et détermine leur visibilité en fonction d'une variable (au bas de celle-ci).

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

    }

}

Alors, comment puis-je déterminer combien de boutons sont visibles pour déterminer ma taille de cellule pour chaque section?


3 commentaires

Mieux vaut incorporer vos boutons dans une vue de pile.


@teja_D et puis il déterminera la hauteur elle-même? Connaissez-vous un exemple / tutoriel qui en parle?


Reportez-vous ceci - stackoverflow.com/questions/30728062/… < / a>


3 Réponses :


0
votes

Et quelque chose comme ça? il suffit de récupérer tous les boutons dans un tableau, puis de les parcourir pour vérifier quels boutons sont masqués et lesquels ne le sont pas. tu pourrais utiliser .isHidden pour les masquer et les afficher, puis vérifier lequel est masqué et renvoyer le numéro.

Exemple de fonction:

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
}


2 commentaires

Il n'y a aucun point à compter car vous pouvez voir un total de 5 UIButton dans le fichier.


Salut @yasser, comment définirais-je cela avec ma mise en page? Je mets .isHidden = true sur certains boutons.



0
votes

Voici comment j'ai fini par le résoudre:

J'ai utilisé sizeForItemAt qui remplace tout le reste et m'a permis d'obtenir ma cellule pour chaque ligne / cas d'utilisation.

En gros, je peux accéder à tous les contrôles liés à ma cellule et déterminer leur visibilité et modifiez la hauteur en fonction de cela.

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 commentaires

0
votes

Utilisez un UIStackView pour mettre en page vos boutons. Lorsque vous définissez les boutons sur .isHidden , la vue de la pile traitera automatiquement la disposition des boutons.

Exemple:

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)

}

Ensuite, vous pouvez calculer la hauteur de la cellule de vue de collection en multipliant le nombre de boutons visibles par la hauteur de bouton que vous avez définie.

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


0 commentaires