Как сделать ImageView UITableViewCell фиксированным, даже когда изображение меньше
У меня есть куча образов, которые я использую для изображений изображения ячеек, они не больше 50х50. например, 40×50, 50×32, 20×37 …..
Когда я загружаю представление таблицы, текст не выстраивается в линию, потому что ширина изображений меняется. Также я хотел бы, чтобы маленькие изображения появлялись в центре, а не слева.
Вот код, который я пытаюсь использовать в моем методе cellForRowAtIndexPath
- Как вы вычисляете день года на определенную дату в Objective-C?
- Как преобразовать значения NSString в шестнадцатеричные значения
- Проблема с кодом: строка формата не является строковым литералом
- Проблема автосохранения кадра UICollectionViewCell contentView в ячейке прототипа Storyboard (Xcode 6, iOS 8 SDK) происходит при запуске только на iOS 7
- IPhone / IPad: Как получить ширину экрана программно?
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];
Как вы видите, я пробовал несколько вещей, но никто из них не работает.
- как создать круглую кнопку?
- Преобразование NSArray в NSDictionary
- UISlider для управления AVAudioPlayer
- глубокая изменчивая копия NSMutableDictionary
- создать подclass uibutton
- Получите данные Exif от UIImage - UIImagePickerController
- Зачем использовать протокол NSObject для реализации протокола
- Есть ли способ указать позицию / индекс аргумента в NSString stringWithFormat?
Нет необходимости переписывать все. Я рекомендую сделать это вместо этого:
Отправьте это в свой .m-файл вашей пользовательской ячейки.
- (void)layoutSubviews { [super layoutSubviews]; self.imageView.frame = CGRectMake(0,0,32,32); }
Это должно сделать трюк красиво. :]
Для тех из вас, у кого нет подclassа 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; }
Приведенный выше код устанавливает размер 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();
Или вы можете использовать другой (не проверенный) подход, предложенный @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();
Приведенный выше код является версией Swift 3+ выше.
Вот как я это сделал. Этот метод обеспечивает правильное перемещение текстовых и текстовых меток влево:
@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 NSString *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; }
просмотр изображения добавить в качестве подmatrix в ячейку таблицы
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];
Целую ячейку не нужно переделывать. Вы можете использовать свойство indentationLevel и indentationWidth tableViewCells для смещения содержимого вашей ячейки. Затем вы добавляете свой собственный образ в левую часть ячейки.
Просто быстро ,
Шаг 1. Создание одного подclassа UITableViewCell
Шаг 2. Добавьте этот метод в SubClass из UITableViewCell
override func layoutSubviews() { super.layoutSubviews() self.imageView?.frame = CGRectMake(0, 0, 10, 10) }
Шаг 3. Создайте объект ячейки, используя этот cellForRowAtIndexPath
в cellForRowAtIndexPath
,
Ex: let customCell:CustomCell = CustomCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
Шаг 4: Наслаждайтесь
Лучше создайте представление изображения и добавьте его в виде суб-представления в ячейку. Затем вы можете получить желаемый размер кадра.
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; }
Это сработало для меня быстро:
Создайте подclass UITableViewCell (убедитесь, что вы связали свою ячейку в раскадровке)
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) } } }
В cellForRowAtIndexPath удалите ячейку в качестве нового типа ячейки:
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyTableCell
Очевидно, изменить числовые значения в соответствии с вашим расположением
Я создал расширение, используя ответ @GermanAttanasio. Он предоставляет способ изменения размера изображения до желаемого размера и другого способа сделать то же самое при добавлении прозрачного поля к изображению (это может быть полезно для представлений таблицы, где вы хотите, чтобы изображение также имело маржу).
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 хорошо работает, чтобы позиционировать вещи, но cell.imageView, похоже, не ведет себя так, как вы этого хотите. Я обнаружил, что это достаточно просто, чтобы заставить UITableViewCell правильно размещаться, сначала предоставив cell.imageView изображение с соответствующим размером, например
// 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;
Затем вы можете просто подключить свой собственный правильно работающий UIImageView с помощью
// 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 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:cell.imageView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]; [cell.imageView addConstraint:aConstraint]; aConstraint = [NSLayoutConstraint constraintWithItem:anImageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:cell.imageView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]; [cell.imageView addConstraint:aConstraint]; aConstraint = [NSLayoutConstraint constraintWithItem:anImageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:kGroupImageDimension]; [cell.imageView addConstraint:aConstraint]; aConstraint = [NSLayoutConstraint constraintWithItem:anImageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:kGroupImageDimension]; [cell.imageView addConstraint:aConstraint]; } else { anImageView = [subviews firstObject]; }
Установите изображение на aImageView, и он будет делать то, что вы ожидаете от UIImageView. Будь то размер, который вы хотите, независимо от изображения, которое вы ему даете. Это должно идти в tableView: cellForRowAtIndexPath:
Это решение по существу рисует изображение как «аспект подгонки» в данном прямоугольнике.
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();
Вот рабочий метод @germanattanasio, написанный для 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() }
Если вы используете cell.imageView?.translatesAutoresizingMaskIntoConstraints = false
вы можете установить ограничения на imageView. Вот рабочий пример, который я использовал в проекте. Я избегал подclassификации и не нуждался в создании раскадровки с ячейками прототипов, но мне потребовалось довольно много времени, чтобы работать, поэтому, вероятно, лучше всего использовать, только если нет более простого или более сжатого способа, доступного вам.
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: String(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 }