Comment faire pour que ImageView d’ITVableViewCell ait une taille fixe même lorsque l’image est plus petite

J’ai un tas d’images que j’utilise pour les vues des cellules, elles ne sont pas plus grandes que 50×50. par exemple 40×50, 50×32, 20×37 …..

Lorsque je charge la vue de table, le texte ne s’aligne pas car la largeur des images varie. J’aimerais aussi que de petites images apparaissent au centre, par opposition à la gauche.

Voici le code que j’essaie dans ma méthode ‘cellForRowAtIndexPath’

cell.imageView.autoresizingMask = ( UIViewAutoresizingNone ); cell.imageView.autoresizesSubviews = NO; cell.imageView.contentMode = UIViewContentModeCenter; cell.imageView.bounds = CGRectMake(0, 0, 50, 50); cell.imageView.frame = CGRectMake(0, 0, 50, 50); cell.imageView.image = [UIImage imageWithData: imageData]; 

Comme vous pouvez le constater, j’ai essayé plusieurs choses, mais aucune ne fonctionne.

Il n’est pas nécessaire de tout réécrire. Je recommande de le faire à la place:

Publiez ceci dans votre fichier .m de votre cellule personnalisée.

 - (void)layoutSubviews { [super layoutSubviews]; self.imageView.frame = CGRectMake(0,0,32,32); } 

Cela devrait bien faire l’affaire. :]

Pour ceux d’entre vous qui n’ont pas de sous-classe de UITableViewCell :

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { [...] CGSize itemSize = CGSizeMake(40, 40); UIGraphicsBeginImageContextWithOptions(itemSize, NO, UIScreen.mainScreen.scale); CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height); [cell.imageView.image drawInRect:imageRect]; cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [...] return cell; } 

Le code ci-dessus définit la taille à 40×40.

Swift 2

  let itemSize = CGSizeMake(25, 25); UIGraphicsBeginImageContextWithOptions(itemSize, false, UIScreen.mainScreen().scale); let imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height); cell.imageView?.image!.drawInRect(imageRect) cell.imageView?.image! = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

Ou vous pouvez utiliser une autre approche (non testée) proposée par @Tommy:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { [...] CGSize itemSize = CGSizeMake(40, 40); UIGraphicsBeginImageContextWithOptions(itemSize, NO, 0.0) [...] return cell; } 

Swift 3+

 let itemSize = CGSize.init(width: 25, height: 25) UIGraphicsBeginImageContextWithOptions(itemSize, false, UIScreen.main.scale); let imageRect = CGRect.init(origin: CGPoint.zero, size: itemSize) cell?.imageView?.image!.draw(in: imageRect) cell?.imageView?.image! = UIGraphicsGetImageFromCurrentImageContext()!; UIGraphicsEndImageContext(); 

Le code ci-dessus est la version 3+ de Swift ci-dessus.

Voici comment je l’ai fait. Cette technique permet de déplacer les étiquettes de texte et de texte de manière appropriée vers la gauche:

 @interface SizableImageCell : UITableViewCell {} @end @implementation SizableImageCell - (void)layoutSubviews { [super layoutSubviews]; float desiredWidth = 80; float w=self.imageView.frame.size.width; if (w>desiredWidth) { float widthSub = w - desiredWidth; self.imageView.frame = CGRectMake(self.imageView.frame.origin.x,self.imageView.frame.origin.y,desiredWidth,self.imageView.frame.size.height); self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x-widthSub,self.textLabel.frame.origin.y,self.textLabel.frame.size.width+widthSub,self.textLabel.frame.size.height); self.detailTextLabel.frame = CGRectMake(self.detailTextLabel.frame.origin.x-widthSub,self.detailTextLabel.frame.origin.y,self.detailTextLabel.frame.size.width+widthSub,self.detailTextLabel.frame.size.height); self.imageView.contentMode = UIViewContentModeScaleAspectFit; } } @end ... - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSSsortingng *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[SizableImageCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } cell.textLabel.text = ... cell.detailTextLabel.text = ... cell.imageView.image = ... return cell; } 

vue d’image append en tant que sous-vue à la cellule tableview

 UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(20, 5, 90, 70)]; imgView.backgroundColor=[UIColor clearColor]; [imgView.layer setCornerRadius:8.0f]; [imgView.layer setMasksToBounds:YES]; [imgView setImage:[UIImage imageWithData: imageData]]; [cell.contentView addSubview:imgView]; 

La cellule entière n’a pas besoin d’être refaite. Vous pouvez utiliser la propriété indentationLevel et indentationWidth des tablesViewCells pour décaler le contenu de votre cellule. Ensuite, vous ajoutez votre imageView personnalisée sur le côté gauche de la cellule.

Un tout simplement rapide ,

Étape 1: Créer une sous-classe de UITableViewCell
Étape 2: Ajoutez cette méthode à SubClass de UITableViewCell

 override func layoutSubviews() { super.layoutSubviews() self.imageView?.frame = CGRectMake(0, 0, 10, 10) } 

Étape 3: Créer un object cellule en utilisant cette SubClass dans cellForRowAtIndexPath ,

 Ex: let customCell:CustomCell = CustomCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") 

Étape 4: Profitez

Il est préférable de créer une vue d’image et de l’append en tant que sous-vue à la cellule. Vous pouvez ensuite obtenir la taille d’image souhaitée.

 UIImage *image = cell.imageView.image; UIGraphicsBeginImageContext(CGSizeMake(35,35)); // draw scaled image into thumbnail context [image drawInRect:CGRectMake(5, 5, 35, 35)]; // UIImage *newThumbnail = UIGraphicsGetImageFromCurrentImageContext(); // pop the context UIGraphicsEndImageContext(); if(newThumbnail == nil) { NSLog(@"could not scale image"); cell.imageView.image = image; } else { cell.imageView.image = newThumbnail; } 

Cela a fonctionné pour moi rapidement:

Créez une sous-classe de UITableViewCell (assurez-vous de lier votre cellule dans le storyboard)

 class MyTableCell:UITableViewCell{ override func layoutSubviews() { super.layoutSubviews() if(self.imageView?.image != nil){ let cellFrame = self.frame let textLabelFrame = self.textLabel?.frame let detailTextLabelFrame = self.detailTextLabel?.frame let imageViewFrame = self.imageView?.frame self.imageView?.contentMode = .ScaleAspectFill self.imageView?.clipsToBounds = true self.imageView?.frame = CGRectMake((imageViewFrame?.origin.x)!,(imageViewFrame?.origin.y)! + 1,40,40) self.textLabel!.frame = CGRectMake(50 + (imageViewFrame?.origin.x)! , (textLabelFrame?.origin.y)!, cellFrame.width-(70 + (imageViewFrame?.origin.x)!), textLabelFrame!.height) self.detailTextLabel!.frame = CGRectMake(50 + (imageViewFrame?.origin.x)!, (detailTextLabelFrame?.origin.y)!, cellFrame.width-(70 + (imageViewFrame?.origin.x)!), detailTextLabelFrame!.height) } } } 

Dans cellForRowAtIndexPath, désélectionnez la cellule en tant que nouveau type de cellule:

  let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyTableCell 

Évidemment, modifiez les valeurs de nombre en fonction de votre mise en page

J’ai créé une extension en utilisant la réponse de @GermanAttanasio. Il fournit une méthode pour redimensionner une image à la taille souhaitée et une autre méthode pour faire la même chose tout en ajoutant une marge transparente à l’image (cela peut être utile pour les vues de table où l’image doit également avoir une marge).

 import UIKit extension UIImage { /// Resizes an image to the specified size. /// /// - Parameters: /// - size: the size we desire to resize the image to. /// /// - Returns: the resized image. /// func imageWithSize(size: CGSize) -> UIImage { UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale); let rect = CGRectMake(0.0, 0.0, size.width, size.height); drawInRect(rect) let resultingImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultingImage } /// Resizes an image to the specified size and adds an extra transparent margin at all sides of /// the image. /// /// - Parameters: /// - size: the size we desire to resize the image to. /// - extraMargin: the extra transparent margin to add to all sides of the image. /// /// - Returns: the resized image. The extra margin is added to the input image size. So that /// the final image's size will be equal to: /// `CGSize(width: size.width + extraMargin * 2, height: size.height + extraMargin * 2)` /// func imageWithSize(size: CGSize, extraMargin: CGFloat) -> UIImage { let imageSize = CGSize(width: size.width + extraMargin * 2, height: size.height + extraMargin * 2) UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.mainScreen().scale); let drawingRect = CGRect(x: extraMargin, y: extraMargin, width: size.width, height: size.height) drawInRect(drawingRect) let resultingImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultingImage } } 

UITableViewCell normal fonctionne bien pour positionner les choses, mais le cell.imageView ne semble pas se comporter comme vous le souhaitez. J’ai trouvé que c’est assez simple pour que UITableViewCell se mette en forme correctement en donnant d’abord à cell.imageView une image de taille correcte comme

 // Putting in a blank image to make sure text always pushed to the side. UIGraphicsBeginImageContextWithOptions(CGSizeMake(kGroupImageDimension, kGroupImageDimension), NO, 0.0); UIImage *blank = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); cell.imageView.image = blank; 

Ensuite, vous pouvez simplement connecter votre propre UIImageView qui fonctionne correctement avec

 // The cell.imageView increases in size to accomodate the image given it. // We don't want this behaviour so we just attached a view on top of cell.imageView. // This gives us the positioning of the cell.imageView without the sizing // behaviour. UIImageView *anImageView = nil; NSArray *subviews = [cell.imageView subviews]; if ([subviews count] == 0) { anImageView = [[UIImageView alloc] init]; anImageView.translatesAutoresizingMaskIntoConstraints = NO; [cell.imageView addSubview:anImageView]; NSLayoutConstraint *aConstraint = [NSLayoutConstraint constraintWithItem:anImageView atsortingbute:NSLayoutAtsortingbuteCenterX relatedBy:NSLayoutRelationEqual toItem:cell.imageView atsortingbute:NSLayoutAtsortingbuteCenterX multiplier:1.0 constant:0.0]; [cell.imageView addConstraint:aConstraint]; aConstraint = [NSLayoutConstraint constraintWithItem:anImageView atsortingbute:NSLayoutAtsortingbuteCenterY relatedBy:NSLayoutRelationEqual toItem:cell.imageView atsortingbute:NSLayoutAtsortingbuteCenterY multiplier:1.0 constant:0.0]; [cell.imageView addConstraint:aConstraint]; aConstraint = [NSLayoutConstraint constraintWithItem:anImageView atsortingbute:NSLayoutAtsortingbuteWidth relatedBy:NSLayoutRelationEqual toItem:nil atsortingbute:NSLayoutAtsortingbuteNotAnAtsortingbute multiplier:0.0 constant:kGroupImageDimension]; [cell.imageView addConstraint:aConstraint]; aConstraint = [NSLayoutConstraint constraintWithItem:anImageView atsortingbute:NSLayoutAtsortingbuteHeight relatedBy:NSLayoutRelationEqual toItem:nil atsortingbute:NSLayoutAtsortingbuteNotAnAtsortingbute multiplier:0.0 constant:kGroupImageDimension]; [cell.imageView addConstraint:aConstraint]; } else { anImageView = [subviews firstObject]; } 

Définissez l’image sur une imageImageView et elle fera ce que vous attendez d’un UIImageView. Soyez la taille que vous voulez, quelle que soit l’image que vous lui donnez. Cela devrait aller dans tableView: cellForRowAtIndexPath:

Cette solution dessine essentiellement l’image en «ajustement d’aspect» dans le rectangle donné.

 CGSize itemSize = CGSizeMake(80, 80); UIGraphicsBeginImageContextWithOptions(itemSize, NO, UIScreen.mainScreen.scale); UIImage *image = cell.imageView.image; CGRect imageRect; if(image.size.height > image.size.width) { CGFloat width = itemSize.height * image.size.width / image.size.height; imageRect = CGRectMake((itemSize.width - width) / 2, 0, width, itemSize.height); } else { CGFloat height = itemSize.width * image.size.height / image.size.width; imageRect = CGRectMake(0, (itemSize.height - height) / 2, itemSize.width, height); } [cell.imageView.image drawInRect:imageRect]; cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

Voici la méthode de travail de @germanattanasio, écrite pour Swift 3

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { ... cell.imageView?.image = myImage let itemSize = CGSize(width:42.0, height:42.0) UIGraphicsBeginImageContextWithOptions(itemSize, false, 0.0) let imageRect = CGRect(x:0.0, y:0.0, width:itemSize.width, height:itemSize.height) cell.imageView?.image!.draw(in:imageRect) cell.imageView?.image! = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() } 

Si vous utilisez cell.imageView?.translatesAutoresizingMaskIntoConstraints = false vous pouvez définir des contraintes sur l’imageView. Voici un exemple de travail que j’ai utilisé dans un projet. J’ai évité le sous-classement et je n’ai pas eu besoin de créer un storyboard avec des cellules prototypes, mais il m’a fallu pas mal de temps pour fonctionner, donc il vaut mieux ne l’utiliser que s’il n’y a pas de moyen plus simple ou plus concis.

 override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 80 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .subtitle, reuseIdentifier: Ssortingng(describing: ChangesRequiringApprovalTableViewController.self)) let record = records[indexPath.row] cell.textLabel?.text = "Title text" if let thumb = record["thumbnail"] as? CKAsset, let image = UIImage(contentsOfFile: thumb.fileURL.path) { cell.imageView?.contentMode = .scaleAspectFill cell.imageView?.image = image cell.imageView?.translatesAutoresizingMaskIntoConstraints = false cell.imageView?.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor).isActive = true cell.imageView?.widthAnchor.constraint(equalToConstant: 80).rowHeight).isActive = true cell.imageView?.heightAnchor.constraint(equalToConstant: 80).isActive = true if let textLabel = cell.textLabel { let margins = cell.contentView.layoutMarginsGuide textLabel.translatesAutoresizingMaskIntoConstraints = false cell.imageView?.trailingAnchor.constraint(equalTo: textLabel.leadingAnchor, constant: -8).isActive = true textLabel.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true textLabel.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true let bottomConstraint = textLabel.bottomAnchor.constraint(equalTo: margins.bottomAnchor) bottomConstraint.priority = UILayoutPriorityDefaultHigh bottomConstraint.isActive = true if let description = cell.detailTextLabel { description.translatesAutoresizingMaskIntoConstraints = false description.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true description.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true cell.imageView?.trailingAnchor.constraint(equalTo: description.leadingAnchor, constant: -8).isActive = true textLabel.bottomAnchor.constraint(equalTo: description.topAnchor).isActive = true } } cell.imageView?.clipsToBounds = true } cell.detailTextLabel?.text = "Detail Text" return cell }