即使图像较小,如何使UITableViewCell的ImageView成为固定大小
我有一大堆用于单元格图像视图的图像,它们都不大于50×50。 例如40×50,50×32,20×37 ……
当我加载表视图时,由于图像的宽度变化,文本不排列。 此外,我希望小图像出现在中心,而不是在左边。
这是我在我的'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];
正如你可以看到我已经尝试了一些东西,但没有一个工作。
它不需要重写所有的东西,我build议这样做。
将其发布到您的自定义单元的.m文件中。
- (void)layoutSubviews { [super layoutSubviews]; self.imageView.frame = CGRectMake(0,0,32,32); }
这应该很好地做到这一点。 :]
对于那些没有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。
迅速
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();
或者您可以使用@Tommybuild议的另一种(未testing)方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { [...] CGSize itemSize = CGSizeMake(40, 40); UIGraphicsBeginImageContextWithOptions(itemSize, NO, 0.0) [...] return cell; }
这是我做的。 这种技术负责将文本和细节文本标签正确地移动到左侧:
@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; }
图像视图作为子视图添加到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];
整个单元不需要重新制作。 你可以使用tableViewCells的indentationLevel和indentationWidth属性来移动你的单元格的内容。 然后,将自定义的imageView添加到单元格的左侧。
最好创build一个图像视图,并将其作为子视图添加到单元格。然后您可以获得所需的帧大小。
一个简单的快速 ,
第1步:创build一个UITableViewCell
子类
第2步:将此方法添加到UITableViewCell的子类
override func layoutSubviews() { super.layoutSubviews() self.imageView?.frame = CGRectMake(0, 0, 10, 10) }
第3步:使用cellForRowAtIndexPath
该子类创build单元格对象,
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; }
我用@GermanAttanasio的答案创build了一个扩展。 它提供了一种将图像调整为所需大小的方法,另一种方法是在为图像添加透明边距的同时执行相同的操作(对于希望图像也有边距的表格视图,这可能很有用)。
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似乎并不像你想要的那样。 我发现这很简单,通过首先给cell.imageView一个正确大小的图像,让UITableViewCell正确布局
// 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]; }
在一个ImageView上设置图像,它会做你所期望的UIImageView。 不pipe你给的图像是你想要的尺寸。 这应该在tableView:cellForRowAtIndexPath:
这在迅速为我工作:
创build一个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中,将单元格作为新的单元格types出列:
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyTableCell
显然改变数字值以适应你的布局
这种解决scheme实质上是在给定的矩形内将图像绘制为“方面适合”。
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
,则可以在cell.imageView?.translatesAutoresizingMaskIntoConstraints = false
上设置约束条件。 这是我在一个项目中使用的一个工作示例。 我避免了子类化,也不需要用原型单元创build故事板,但是花了我很长一段时间才能开始运行,所以如果没有更简单或更简洁的方法,最好只用。
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 }