2010-06-28 5 views
10

J'essaie de placer des images de différentes tailles dans imageView de UITableViewCell. J'obtiens les données d'image asynch'ly, crée l'image, place le mode de contenu de imageView et fixe finalement des limites de imageView. Mais le code semble insensible à tous les changements que j'ai faits. Je veux que les images soient centrées dans une zone de 75x75. J'ai écrit le code ci-dessous à cet effetModification des limites d'imageView de UITableViewCell

UIImage* image = [UIImage imageWithData:data]; 
[holder.imageView setContentMode:UIViewContentModeCenter || UIViewContentModeRedraw]; 
[holder.imageView setImage:image]; 
[holder.imageView setBounds:CGRectMake(0,0,75,75)]; 
[holder.imageView setFrame:CGRectMake(0,0,75,75)]; 
[holder setNeedsLayout]; 

Où holder est UITableViewCell. Le résultat que je reçois est toujours le même. Toutes les images ont une hauteur de 75 pixels et des largeurs différentes. Quelqu'un peut-il m'aider à résoudre ce problème?

J'ai réalisé que la définition des propriétés contentMode et bounds n'a aucun effet sur ce code. J'ai ajouté un NSLog après la dernière ligne et a obtenu les résultats comme suit:

NSLog(@"imageview:%@ bounds and contentMode:%@ %@",[holder imageView],[holder.imageView bounds],[holder.imageView contentMode]); 

imageview: < UIImageView: 0x39ab8a0; cadre = (0 0; 75 75); opaque = NON; userInteractionEnabled = NO; couche = < CALayer: 0x39a92b0 >> bornes et contentMode: (null) (null)

pas de solution

Répondre

42

DONE, j'ai finalement trouvé la solution, ça m'a coûté 3 heures =) Bien que

la solution consiste à modifier les propriétés comme lié, cadre, contentMode en - (void) me layoutSubviews le nom de la classe personnalisée UITableViewCell. Le "truc" est d'écrire du code de disposition dans cette méthode, sinon le code n'a aucun effet.

Ci-dessous le code a fait le travail pour moi. Il rend les lignes de la table alignées verticalement.

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    self.imageView.bounds = CGRectMake(0,0,75,75); 
    self.imageView.frame = CGRectMake(0,0,75,75); 
    self.imageView.contentMode = UIViewContentModeScaleAspectFit; 

    CGRect tmpFrame = self.textLabel.frame; 
    tmpFrame.origin.x = 77; 
    self.textLabel.frame = tmpFrame; 

    tmpFrame = self.detailTextLabel.frame; 
    tmpFrame.origin.x = 77; 
    self.detailTextLabel.frame = tmpFrame; 

} 
+0

Bummer, je pensais que je pourrais être obligé de créer une autre sous-classe UITableViewCell ... merci d'avoir pris le temps de le confirmer pour moi! –

+1

Je dois convenir que c'est une énorme perte de temps pour que cela fonctionne comme prévu. –

+0

Alors que cela fonctionne, c'est toujours un hack. On s'attendrait à ce que l'image/les limites soient élaborées à partir des contraintes définies dans l'UITableViewCell personnalisé. –

1

encore essayez de changer la propriété "contentMode" de imageView à 'UIViewContentModeScaleAspectFit' ou 'UIViewContentModeScaleAspectFill'

+1

Merci, je l'ai essayé votre recommandation, mais cela n'a pas fonctionné. J'ai réalisé que quelle que soit la valeur que j'ai définie pour contentMode et bounds n'a aucun effet. J'ai édité mon premier post pour refléter cela. –

2

"UIViewContentModeCenter || UIViewContentModeRedraw" est équivalent à 1. Il est pas non plus un champ de bits. Vous voulez UIViewContentModeCenter.

UITableViewCell.imageView est géré par la cellule. Si vous voulez la mise en page personnalisée, essayez d'ajouter une vue à contentView (je devine ce que vous entendez par « centrée dans une zone de 75x75 »):

UIImageView * iv = [[[UIImageView alloc] initWithImage:image] autorelease]; 
iv.frame = (CGRect){{0,0},{75,75}}; 
iv.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin| UIViewAutoresizingFlexibleRightMargin; 
iv.contentMode = UIViewContentModeScaleAspectFit; 
[holder.contentView addSubview:iv]; 
+0

Merci! J'ai résolu le problème sans utiliser la vue de contenu. Je vais marquer la question comme répondue après 2 jours =) –

10

Le problème avec de UITableViewCell est que vous avez aucun contrôle sur la taille des objets intégrés (à savoir imageView, contentView, accessoryView, backgroundView). Lorsque la table change, vos personnalisations sont piétinées. Vous pouvez, comme l'a souligné Behlul, forcer les tailles à corriger en utilisant layoutSubviews, mais le problème est que layoutSubviews est appelé à chaque fois que la table défile. C'est beaucoup d'appels de re-disposition inutiles.

Une autre méthode consiste à ajouter tous de votre contenu au contentView.De même, si vous personnalisez l'arrière-plan, vous pouvez créer un fond transparent backgroundView et ajouter votre vue d'arrière-plan personnalisée (par exemple myBackgroundView) en tant que sous-vue de backgroundView.

De cette façon, vous pouvez placer et dimensionner vos articles comme vous les voulez. Le côté négatif est que les messages de stock ne sont plus reçus des vues de l'accessoire ou de l'image. Vous avez juste à créer vous-même.

Espérons que ça aide!

// This code is not tested 
// MyCustomTableViewCell 
- (id) init{ 
    self = [super initWithStyle: UITableViewCellStyleDefault reuseIdentifier:@"MyReuseIdentifier"]; 
    if(self){ 
     //image view 
     my_image_view = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"default_image.png"]] retain]; 
     [my_image_view setFrame:CGRectMake(10,10,30,30)]; 
     [self.contentView addSubview:my_image_view]; 

     //labels 
     my_text_label = [[[UILabel alloc] initWithFrame:CGRectMake(50,10,100,15)] retain]; 
     [self.contentView addSubview:my_text_label]; 
     //set font, etc 

     //detail label 
     my_detail_label = [[[UILabel alloc] initWithFrame:CGRectMake(50,25,100,15)] retain]; 
     [self.contentView addSubview:my_detail_label]; 
     //set font, etc 

     //accessory view 
     //Whatever you want to do here 
     //attach "accessoryButtonTapped" selector to button action 

     //background view 
     UIView* background_view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 50)] autorelease]; 
     [background_view setBackgroundColor:[UIColor greenColor]]; 
     background_view.layer.cornerRadius = 17; 
     background_view.layer.borderWidth = 3; 
     background_view.layer.borderColor = [UIColor whiteColor].CGColor; 

     [self setBackgroundView:[[[UIView alloc] init] autorelease]]; 
     [self.backgroundView addSubview:background_view]; 
    } 

    return self; 
} 

- (void) setLabelText: (NSString*) label_text{ 
    [my_text_label setText:label_text]; 
} 

- (void) setDetailText: (NSString*) detail_text{ 
    [my_detail_label setText: detail_text]; 
} 

- (void) accessoryButtonTapped{ 
    //call table view delegate's accessoryButtonTappedForRowWithIndexPath method 
} 
+0

C'est en fait la meilleure méthode que la réponse sélectionnée. Vous pouvez également créer un UITableViewCell via un xib, si vous le souhaitez. Voici un tutoriel à ce sujet: http://ijoshsmith.com/2011/07/16/creating-a-custom-uitableviewcell-in-ios-4/ –

+0

Cela a fait l'affaire pour moi. –

0

Créer sous-classe de UITableViewCell:

@interface UITableViewCellSubClass : UITableViewCell 

@end 

@implementation UITableViewCellSubClass 

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    self.imageView.frame = CGRectMake(0,4,32,32); 
    self.textLabel.frame = CGRectMake(42,4,300,32); 
} 
@end 
Questions connexes