Comment définir la largeur d'une cellule dans un UITableView dans un style groupé

107

Je travaille dessus depuis environ 2 jours, alors j'ai pensé partager mes apprentissages avec vous.

La question est: est-il possible de réduire la largeur d'une cellule dans un UITableView groupé?

La réponse est non.

Mais il existe deux façons de contourner ce problème.

Solution n ° 1: Une table plus fine Il est possible de changer le cadre de la tableView, afin que la table soit plus petite. Cela entraînera le rendu UITableView de la cellule à l'intérieur avec la largeur réduite.

Une solution pour cela peut ressembler à ceci:

-(void)viewWillAppear:(BOOL)animated
{
    CGFloat tableBorderLeft = 20;
    CGFloat tableBorderRight = 20;

    CGRect tableRect = self.view.frame;
    tableRect.origin.x += tableBorderLeft; // make the table begin a few pixels right from its origin
    tableRect.size.width -= tableBorderLeft + tableBorderRight; // reduce the width of the table
    tableView.frame = tableRect;
}

Solution n ° 2: avoir des cellules rendues par des images

Cette solution est décrite ici: http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html

J'espère que cette information te sera utile. Il m'a fallu environ 2 jours pour essayer de nombreuses possibilités. C'est ce qui restait.

Tomen
la source
3
Je pense que cela aurait dû être mis en place comme une question avec juste la deuxième ligne ("La question est: ..."), puis la solution n ° 1 et la solution n ° 2 affichées comme deux réponses distinctes, l'une d'elles étant acceptée. Ensuite, si d'autres utilisateurs ajoutent leurs propres réponses et que l'une d'entre elles finit par être meilleure, la réponse acceptée peut être modifiée plus tard.
GeneralMike

Réponses:

226

Un moyen meilleur et plus propre d'y parvenir consiste à sous-classer UITableViewCell et à remplacer sa -setFrame:méthode comme suit :

- (void)setFrame:(CGRect)frame {
    frame.origin.x += inset;
    frame.size.width -= 2 * inset;
    [super setFrame:frame];
}

Pourquoi est-ce mieux? Parce que les deux autres sont pires.

  1. Ajuster la largeur de la vue du tableau dans -viewWillAppear:

    Tout d'abord, cela n'est pas fiable, le contrôleur de vue supervisée ou de vue parent peut ajuster le cadre de vue de la table après l' -viewWillAppear:appel. Bien sûr, vous pouvez sous- -setFrame:classer et remplacer pour votre UITableView comme ce que je fais ici pour UITableViewCells. Cependant, sous-classer UITableViewCells est une méthode très courante, légère et Apple.

    Deuxièmement, si votre UITableView a backgroundView, vous ne voulez pas que son backgroundView soit réduit ensemble. Garder la largeur de backgroundView tout en réduisant la largeur de UITableView n'est pas un travail trivial, sans oublier que l'expansion des sous-vues au-delà de sa supervision n'est pas une chose très élégante à faire en premier lieu.

  2. Rendu de cellule personnalisé pour simuler une largeur plus étroite

    Pour ce faire, vous devez préparer des images d'arrière-plan spéciales avec des marges horizontales et vous devez disposer vous-même des sous-vues des cellules pour tenir compte des marges. En comparaison, si vous ajustez simplement la largeur de la cellule entière, le redimensionnement automatique fera tout le travail pour vous.

an0
la source
2
c'est une solution sympa et élégante, je l'ai fait dans une catégorie :) Je note aussi que plus les objets sont transparents, plus la charge du processeur est importante :)
mister koz
11
@misterkoz - un mot d'avertissement: certains contrôles iOS (UIDatePicker pour défini) utilisent en interne UITableViewCells et se cassent si vous implémentez cela dans une catégorie.
Clafou
7
Cette méthode ne semble pas fonctionner dans iOS8 lorsque vous essayez de supprimer une cellule en mode édition. Le setFrame est appelé lorsque vous entrez / sortez du mode d'édition afin que la cellule ne cesse de rétrécir. Une solution à cela?
John Baum
3
@JohnBaum cela pourrait aider (au moins dans mon cas, cela fonctionne): stackoverflow.com/questions/25911484/ios-8-cell-resizing
...
2
Cette solution est vraiment une aubaine. Au cas où quelqu'un se demanderait comment faire de même dans swift - reddit.com/r/swift/comments/2fr849/…
sysuser
16

Pour ce faire dans Swift, qui ne fournit pas de méthodes pour définir les variables, vous devrez remplacer le setter pour frame. Publié à l'origine (du moins là où je l'ai trouvé) ici

override var frame: CGRect {
    get {
        return super.frame
    }
    set (newFrame) {
        let inset: CGFloat = 15
        var frame = newFrame
        frame.origin.x += inset
        frame.size.width -= 2 * inset
        super.frame = frame
    }
}
JuJoDi
la source
Works for swift
Simon McNeil
9

Si rien ne fonctionne, vous pouvez essayer ceci

Faites de la couleur d'arrière-plan de la cellule une couleur claire, puis placez une image de la cellule avec la taille requise. Si vous souhaitez afficher du texte sur cette cellule, placez une étiquette au-dessus de l'image. N'oubliez pas de définir la couleur d'arrière-plan de l'étiquette également sur la couleur claire.

includeMe
la source
8

J'ai trouvé que la solution acceptée ne fonctionnait pas lors de la rotation. Pour obtenir des cellules UITableViewCells avec des largeurs fixes et des marges flexibles, je viens d'adapter la solution ci-dessus à ce qui suit:

- (void)setFrame:(CGRect)frame {

    if (self.superview) {
        float cellWidth = 500.0;
        frame.origin.x = (self.superview.frame.size.width - cellWidth) / 2;
        frame.size.width = cellWidth;
    }

    [super setFrame:frame];
}

La méthode est appelée chaque fois que le périphérique tourne, de sorte que les cellules seront toujours centrées.

Graham
la source
0

Il existe une méthode qui est appelée lors de la rotation de l'écran: viewWillTransitionToSize

C'est là que vous devez redimensionner le cadre. Voir exemple. Modifiez les coordonnées du cadre selon vos besoins.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        int x = 0;
        int y = 0;
        self.tableView.frame = CGRectMake(x, y, 320, self.tableView.frame.size.height);
    }];
}
Gars
la source
-2

je le fais dans

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    CGFloat tableBorderLeft = self.view.frame.origin.x + 10;
    CGFloat tableBorderRight = self.view.frame.size.width - 20;

    CGRect tableRect = self.view.frame;
    tableRect.origin.x = tableBorderLeft; 
    tableRect.size.width = tableBorderRight; 
    tableView.frame = tableRect;
}

Et cela a fonctionné pour moi

Lều Đức Quý
la source
-6

Dans le fichier .h, ajoutez le délégué 'UITableViewDataSource'

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ 
    return size;
}
bharath gangupalli
la source
4
Il veut définir la largeur, pas la hauteur
Christopher Pickslay
oh hoo. Sry pour les inconvénients.
bharath gangupalli
Vous comprenez mal la question et vous répondez pour la hauteur et vous savez ce que cela fonctionne pour moi parce que je recherche la hauteur et non la largeur ... merci pour la réponse
Pooja