UITableViewCell:如何在视网膜显示上给内置的 imageView 一个边距
Posted
技术标签:
【中文标题】UITableViewCell:如何在视网膜显示上给内置的 imageView 一个边距【英文标题】:UITableViewCell: how to give the built-in imageView a margin on retina display 【发布时间】:2011-02-05 19:03:53 【问题描述】:我想在普通旧 UITableViewCell(分组样式)左侧的 UIImageView 上应用边距。
我发现的唯一方法(通过here)是在将 UIImage 附加到 UIImageView 之前调整它本身的大小。如果图像比单元格小,它将居中;留下所需的边距作为副作用。
嗯,这行得通,但现在我的图像很模糊,因为 100 unit 行高在 iPhone4 上不是 100 pixels,而是 200。所以我最终得到缩放到 90x90 pixels 的 UIImage,生成 90x90 unit(180x180 像素)的 UIImageView 图像。输入丑陋的模糊。
所以我的问题是:如何在不过度下采样图像的情况下实现 imageView 周围的边距? (理想情况下根本不需要下采样 - 我需要保留原件以备后用)。
我觉得我错过了一些明显的东西;我真的不想为此实现自定义单元类。
【问题讨论】:
【参考方案1】:谢谢大家,我想出了一个不需要子类化的“解决方案”。
我所做的仍然是对图像进行下采样,但缩小到 2 倍大小(问题示例中的 180x180)。 然后,当我从我使用的处理过的 CGImage 创建最终的 UIImage 时:
<em>UIImage:</em> +(UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
并将 scale: 设置为 2。现在一切正常。但我仍在创建重复图像只是为了让 UIKit 满意。
【讨论】:
【参考方案2】:在你的 UITableViewCell 子类中实现这个方法
-(void) layoutSubviews
[super layoutSubviews];
self.imageView.frame = CGRectInset(self.imageView.frame, 5, 5);
【讨论】:
或者在 UITableViewCell 上创建一个具有此属性的类别,并具有一个额外的结构或 CGSize 属性,您可以将其设置为 5、5 或任何您需要的值。【参考方案3】:注意:我还没有测试过这些,所以UITableViewCell
可能会覆盖其中的一些设置,以根据自己的内部逻辑布置其子视图。
您是否尝试过仅调整图像视图的框架?试试这个:
UITableViewCell * tableViewCell = [[[UITableViewCell alloc] init] autorelease];
tableViewCell.imageView.image = [UIImage imageNamed:@"table-view-image"];
CGRect imageViewFrame = tableViewCell.imageView.frame;
imageViewFrame.origin.x += 10.0f;
tableViewCell.imageView.frame = imageViewFrame;
这只会使图像视图比其正常的x
坐标多 10 个点。如果要两边都pad,也可以把image view上的contentMode
属性设置为UIViewContentModeCenter
,并调整它的宽度:
UITableViewCell * tableViewCell = [[[UITableViewCell alloc] init] autorelease];
tableViewCell.imageView.image = [UIImage imageNamed:@"table-view-image"];
tableViewCell.imageView.contentMode = UIViewContentModeCenter;
CGRect imageViewFrame = tableViewCell.imageView.frame;
imageViewFrame.size.width += 20.0f;
tableViewCell.imageView.frame = imageViewFrame;
这将使图像视图宽 20 点,但由于内容模式设置为居中,图像将在不拉伸的情况下绘制。如果您的图像尺寸正确,这将有效地将图像在左右两侧填充 10 个点。但是,您需要注意,如果您这样做,您提供的UIImage
必须已经是适合图像视图的确切尺寸。 contentMode
的默认设置是UIViewContentModeScaleToFill
,所以它会自动缩放图像以填充图像视图的框架。将其设置为 UIViewContentModeCenter
将不再执行此操作,但会将实际图像居中。
【讨论】:
【参考方案4】:在我的例子中,我使用了我自己的继承自 UITableViewCell
的子类。
它非常干净且易于使用。
此外,我可以使用不同大小的图像来调整此单元格的大小。
关键是使用将替换常规imageView
的附加属性@
1:在子类中,我添加了一个属性mainImageView
,可以用来代替imageView
。
@property (nonatomic, retain) UIImageView *mainImageView;
2:然后在- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
。
我分配并初始化了mainImageView
。
您可以为mainImageView
设置任何框架(矩形)。
将其作为子视图添加到contentView
。
我使用insetImageView
将其与 `contentView' 的垂直中间对齐。
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
// Initialization code.
mainImageView = [[UIImageView alloc] initWithFrame:frameCellMainImageView];
[self.contentView addSubview:mainImageView];
insetImageView = (sizeRowHeightTwoLinedDetail - frameCellMainImageView.size.height) / 2.0;
return self;
3:覆盖- (void)layoutSubviews
以确保textLabel
、detailTextLabel
等其他属性将其框架设置为与添加属性mainImageView
相得益彰
- (void)layoutSubviews
[super layoutSubviews];
CGRect frameImageView = frameCellMainImageView;
frameImageView.origin.x = insetImageView;
frameImageView.origin.y = insetImageView;
[self.mainImageView setFrame:frameImageView];
// Use changed frame
frameImageView = self.mainImageView.frame;
CGFloat newLeftInset = frameImageView.size.width + insetImageView;
CGRect frameTextLabel = self.textLabel.frame;
CGRect frameDetailLabel = self.detailTextLabel.frame;
frameTextLabel.origin.x += newLeftInset;
frameDetailLabel.origin.x += newLeftInset;
CGFloat newTextWidth = 320.0;
newTextWidth -= newLeftInset;
newTextWidth -= insetImageView;
newTextWidth -= insetImageView;
frameTextLabel.size.width = newTextWidth;
frameDetailLabel.size.width = newTextWidth;
[self.textLabel setFrame:frameTextLabel];
[self.detailTextLabel setFrame:frameDetailLabel];
4:在UITableDataSourceDelegate
方法中使用此单元格时,使用cell.mainImageView
接收消息,而不是常规的cell.imageView
【讨论】:
以上是关于UITableViewCell:如何在视网膜显示上给内置的 imageView 一个边距的主要内容,如果未能解决你的问题,请参考以下文章
如何在不损失视网膜显示质量的情况下将 UIView 捕获到 UIImage