2
votes

problème lors de la définition de la largeur dynamique de la cellule de vue de collection

J'essaye de définir dynamiquement la largeur de la cellule de vue de collection. Au départ, le rendu n'est pas conforme aux attentes. Mais quand je tape sur la cellule, elle s'ajuste comme je veux. Voici le code que j'ai écrit:

Code

import UIKit

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {

    @IBOutlet weak var collView: UICollectionView!


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

    override func viewDidLoad() {
        super.viewDidLoad()
        let layout = collView?.collectionViewLayout as! UICollectionViewFlowLayout
        layout.itemSize = UICollectionViewFlowLayout.automaticSize
        layout.estimatedItemSize = CGSize(width: 93, height: 40)
        // 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
        }
        cell.layer.borderWidth = 1
        cell.layer.cornerRadius = cell.frame.height / 2
        return cell
    }
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedIndex = indexPath.row
        self.collView.reloadData()
    }
}

ici, je joins deux images avant d'appuyer et après avoir tapé pour que vous puissiez facilement comprendre

[! [Voici l'image avant de toucher

c'est après avoir tapé sur la cellule, ça me donne un résultat parfait sur la cellule] 2 ] 2

alors s'il vous plaît dites-moi ce qui ne va pas dans mon code


1 commentaires

Veuillez ajouter les images de manière appropriée. J'ai édité votre question pour expliquer le problème.


3 Réponses :


2
votes

J'ai trouvé une petite astuce pour swift 4.2

Pour une largeur dynamique et une hauteur fixe:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let label = UILabel(frame: CGRect.zero)
    label.text = textArray[indexPath.item]
    label.sizeToFit()
    return CGSize(width: label.frame.width, height: 32)
}


2 commentaires

Je ne suggère pas d'utiliser sizeToFit. Définissez les contraintes en conséquence.


pouvez-vous s'il vous plaît me dire quelle contrainte je dois donner



3
votes

Dans votre fonction CollectionViewCell override favoriteLayoutAttributesFitting C'est ici que la cellule a la possibilité d'indiquer ses attributs préférés, y compris la taille, que nous calculons à l'aide de la mise en page automatique.

 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 commentaires

1
votes

Il est évident que vous devez utiliser le délégué de mise en page de flux sizeForItemAt pour transmettre la largeur dynamique. Mais la partie délicate est de calculer la largeur de la cellule en fonction du texte. Vous pouvez en fait calculer la largeur d'un texte étant donné que vous avez une police.

Introduisons quelques extensions qui nous aideront tout au long du processus

StringExtensions.swift p >

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let height = 40
    let text = YOUR_TEXT
    let width = text.width(withConstrainedHeight: height, font: Font.regular.withSize(.extraSmall)) + EXTRA_SPACES_FOR_LEFT_RIGHT_PADDING
    return CGSize(width: width, height: height)
}

Cette méthode nous permet de connaître la largeur d'une chaîne, si je lui donne la hauteur et la police. Ensuite, utilisez-le dans sizeForItem comme suit

extension String {

    public func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
        let boundingBox = self.boundingRect(with: constraintRect,
                                        options: .usesLineFragmentOrigin,
                                        attributes: [.font: font], context: nil)

        return ceil(boundingBox.width)
    }
}


0 commentaires