web-dev-qa-db-fra.com

Largeur de cellule dynamique de UICollectionView en fonction de la largeur de l'étiquette

J'ai un UICollectionView, qui charge les cellules d'une cellule réutilisable, qui contient une étiquette. Un tableau fournit un contenu pour cette étiquette. Je peux redimensionner la largeur de l'étiquette en fonction de la largeur du contenu facilement avec sizeToFit. Mais je ne peux pas faire de cellule pour correspondre à l'étiquette.

Voici le code

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    arrayOfStats =  @[@"time:",@"2",@"items:",@"10",@"difficulty:",@"hard",@"category:",@"main"];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:     (NSInteger)section{
    return [arrayOfStats count];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    return CGSizeMake(??????????);
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    Cell *cell = (Cell *) [collectionView dequeueReusableCellWithReuseIdentifier:@"qw" forIndexPath:indexPath];
    cell.myLabel.text = [NSString stringWithFormat:@"%@",[arrayOfStats objectAtIndex:indexPath.item]];
    // make label width depend on text width
    [cell.myLabel sizeToFit];

    //get the width and height of the label (CGSize contains two parameters: width and height)
    CGSize labelSize = cell.myLbale.frame.size;

    NSLog(@"\n width  = %f height = %f", labelSize.width,labelSize.height);

    return cell;
}
75
pulp

Dans sizeForItemAtIndexPath retourne la taille du texte

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    return [(NSString*)[arrayOfStats objectAtIndex:indexPath.row] sizeWithAttributes:NULL];
}
72
Basheer_CAD

Commander ci-dessous le code que vous pourriez donner CGSize très court.

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    NSString *testString = @"SOME TEXT";
    return [testString sizeWithAttributes:NULL];
}
27
Raza.najam

Swift 4.2 +

Le principe est:

  1. Implémente UICollectionViewDelegateFlowLayout (il contient la signature de méthode nécessaire)

  2. Appel collectionView...sizeForItemAt méthode.

  3. Pas besoin de passer le pont String à NSString pour appeler size(withAttributes: méthode. Swift String l'a sorti du carton.

  4. Les attributs sont les mêmes que vous avez définis pour (NS)AttributedString, c'est-à-dire la famille de police, la taille, le poids, etc. Paramètre facultatif.


Exemple de solution:

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return "String".size(withAttributes: nil)
    }
}

Mais vous voudrez probablement spécifier des attributs de chaîne concrets propres à votre cellule. Par conséquent, le retour final ressemblerait à ceci:

// Replace "String" with proper string (typically array element). 
return "String".size(withAttributes: [
    NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14)
])
22
Hexfire

J'ai trouvé un petit truc pour Swift 4.2

Pour largeur dynamique et 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)
    }

Pour hauteur dynamique et largeur 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: 120, height: label.frame.height)
        }
19
Hassan Izhar

Dans Swift 3

let size = (arrayOfStats[indexPath.row] as NSString).size(attributes: nil)
18
Johnson

Swift 4

let size = (arrayOfStats[indexPath.row] as NSString).size(withAttributes: nil)
11
Barath