我有一堆用于细胞图像视图的图像,它们都不超过50x50。例如40x50,50x32,20x37 .....
当我加载表格视图时,文本不会对齐,因为图像的宽度会有所不同。此外,我希望小图像出现在中心而不是左侧。
以下是我在'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];
正如你所看到的,我已经尝试了一些东西,但它们都没有用。
答案 0 :(得分:145)
没有必要重写所有内容。我建议改为:
将此内容发布在自定义单元格的.m文件中。
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.frame = CGRectMake(0,0,32,32);
}
这应该很好地完成。 :
答案 1 :(得分:126)
对于那些没有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;
}
上面的代码将大小设置为40x40。
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+版本。
答案 2 :(得分:33)
我是怎么做到的。此技术负责将文本和详细文本标签适当地移动到左侧:
@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;
}
答案 3 :(得分:21)
图像视图作为子视图添加到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];
答案 4 :(得分:12)
整个细胞不需要重新制作。您可以使用tableViewCells的indentationLevel和indentationWidth属性来移动单元格的内容。然后将自定义imageView添加到单元格的左侧。
答案 5 :(得分:7)
简单 Swift ,
第1步:创建UITableViewCell
的一个子类
第2步:将此方法添加到UITableViewCell的SubClass
override func layoutSubviews() {
super.layoutSubviews()
self.imageView?.frame = CGRectMake(0, 0, 10, 10)
}
第3步:使用cellForRowAtIndexPath
中的子类创建单元格对象,
Ex: let customCell:CustomCell = CustomCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
第4步:享受
答案 6 :(得分:5)
更好地创建图像视图并将其作为子视图添加到单元格中。然后,您可以获得所需的帧大小。
答案 7 :(得分:2)
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;
}
答案 8 :(得分:1)
我使用@GermanAttanasio的答案创建了一个扩展程序。它提供了一种将图像大小调整为所需大小的方法,以及在向图像添加透明边距时执行相同操作的另一种方法(这对于您希望图像也具有边距的表视图非常有用)。 / p>
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
}
}
答案 9 :(得分:1)
这对我来说非常有用:
创建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
显然更改数字值以适合您的布局
答案 10 :(得分:0)
常规UITableViewCell可以很好地定位事物,但是cell.imageView似乎没有像你想要的那样。我发现通过首先给cell.image查看正确大小的图像(如
),可以让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];
}
在onImageView上设置图像,它将执行您期望UIImageView执行的操作。无论您提供的图像如何,都是您想要的尺寸。这应该放在tableView:cellForRowAtIndexPath:
中答案 11 :(得分:0)
此解决方案基本上将图像绘制为“适合方面”。在给定的矩形内。
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();
答案 12 :(得分:0)
这是@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()
}
答案 13 :(得分:0)
如果您使用cell.imageView?.translatesAutoresizingMaskIntoConstraints = false
,则可以在imageView上设置约束。这是我在项目中使用的一个工作示例。我避免了子类化,并且不需要使用原型单元创建故事板,但确实花了我很长时间才能运行,所以最好只在没有更简单或更简洁的方式使用时使用。
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
}
答案 14 :(得分:0)
我有同样的问题。谢谢所有其他回答的人-我能够使用部分答案中的一部分找到解决方案。
我的解决方案是使用Swift 5
我们要解决的问题是,TableViewCell
中的图像可能具有不同的长宽比,但是我们希望它们以一致的宽度进行渲染。图像当然应该没有失真地渲染并填充整个空间。就我而言,我可以“裁剪”一些高个,瘦的图像,所以我使用了内容模式.scaleAspectFill
为此,我创建了UITableViewCell
的自定义子类。就我而言,我将其命名为StoryTableViewCell
。整个课程都粘贴在下面,并带有内联注释。
当我还使用自定义附件视图和长文本标签时,这种方法对我有用。这是最终结果的图像:
Rendered Table View with consistent image width
class StoryTableViewCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
// ==== Step 1 ====
// ensure we have an image
guard let imageView = self.imageView else {return}
// create a variable for the desired image width
let desiredWidth:CGFloat = 70;
// get the width of the image currently rendered in the cell
let currentImageWidth = imageView.frame.size.width;
// grab the width of the entire cell's contents, to be used later
let contentWidth = self.contentView.bounds.width
// ==== Step 2 ====
// only update the image's width if the current image width isn't what we want it to be
if (currentImageWidth != desiredWidth) {
//calculate the difference in width
let widthDifference = currentImageWidth - desiredWidth;
// ==== Step 3 ====
// Update the image's frame,
// maintaining it's original x and y values, but with a new width
self.imageView?.frame = CGRect(imageView.frame.origin.x,
imageView.frame.origin.y,
desiredWidth,
imageView.frame.size.height);
// ==== Step 4 ====
// If there is a texst label, we want to move it's x position to
// ensure it isn't overlapping with the image, and that it has proper spacing with the image
if let textLabel = self.textLabel
{
let originalFrame = self.textLabel?.frame
// the new X position for the label is just the original position,
// minus the difference in the image's width
let newX = textLabel.frame.origin.x - widthDifference
self.textLabel?.frame = CGRect(newX,
textLabel.frame.origin.y,
contentWidth - newX,
textLabel.frame.size.height);
print("textLabel info: Original =\(originalFrame!)", "updated=\(self.textLabel!.frame)")
}
// ==== Step 4 ====
// If there is a detail text label, do the same as step 3
if let detailTextLabel = self.detailTextLabel {
let originalFrame = self.detailTextLabel?.frame
let newX = detailTextLabel.frame.origin.x-widthDifference
self.detailTextLabel?.frame = CGRect(x: newX,
y: detailTextLabel.frame.origin.y,
width: contentWidth - newX,
height: detailTextLabel.frame.size.height);
print("detailLabel info: Original =\(originalFrame!)", "updated=\(self.detailTextLabel!.frame)")
}
// ==== Step 5 ====
// Set the image's content modoe to scaleAspectFill so it takes up the entire view, but doesn't get distorted
self.imageView?.contentMode = .scaleAspectFill;
}
}
}
答案 15 :(得分:0)
我们最终得到的解决方案与许多其他解决方案类似。但是要获得分隔符的正确位置,我们必须在调用super.layoutSubviews()
之前将其设置好。简化示例:
class ImageTableViewCell: UITableViewCell {
override func layoutSubviews() {
separatorInset.left = 70
super.layoutSubviews()
imageView?.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
textLabel?.frame = CGRect(x: 70, y: 0, width: 200, height: 50)
}
}