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
alors s'il vous plaît dites-moi ce qui ne va pas dans mon code
3 Réponses :
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) }
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
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 }
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) } }
Veuillez ajouter les images de manière appropriée. J'ai édité votre question pour expliquer le problème.