UITableViewCell: How to Provide an Inline Image View Margin on Retina Screen

I would like to apply a marker to the UIImageView to the left of the plain old UITableViewCell (grouped style).

The only way I found to do this (via here ) is to resize the UIImage itself before attaching it to the UIImageView. If the image is smaller than the cell, it will be centered; leaving the desired margin as a side effect.

Well, it works, but now my image is blurry, because the height of the 100-line row is not 100 pixels on iPhone4, its 200. Thus, I get a UIImage scaled to 90x90 pixels, which creates a 90x90 block (180x180 pixels) Image UIImageView . Enter the ugly blur.

So my question is: how do I achieve markup around imageView without unnecessarily lowering it for my image? (ideally, without downsampling at all - I need to save the original for later in any case).

I feel that I am missing something obvious; I really don't want to implement my own cell class just for this.

+4
source share
4 answers

Thanks guys, I came up with a β€œsolution” that does not require a subclass.

What I am doing is still reducing the image size, but down to 2x (180x180 from the example in the question). Then, when I came to create the final UIImage from the processed CGImage, I use:

UIImage: +(UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation

and set the scale: to 2. Now everything works. But I'm still creating duplicate images to keep UIKit happy.

+3
source

Inject this method into a subclass of UITableViewCell

 -(void) layoutSubviews { [super layoutSubviews]; self.imageView.frame = CGRectInset(self.imageView.frame, 5, 5); } 
+2
source

Note: I have not tested this, so it is possible that the UITableViewCell override some of these parameters to lay out its subtasks in accordance with its own internal logic.

Did you try to just adjust the frame for viewing the image? Try the following:

 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; 

This will result in a simple display of the image 10 points larger than its normal x coordinate. If you want to place both sides, you can also set the contentMode property to the image view on the UIViewContentModeCenter and adjust its width:

 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; 

This will make the image 20 points wider, but since the content mode is set to the center, the image will be drawn without stretching. If the dimensions of your image are correct, this will effectively place the image 10 points to the left and right. However, you need to know that if you do this, the UIImage that you provide should already be the exact sizes corresponding to the size of the image. contentMode default setting of UIViewContentModeScaleToFill , so it automatically scales the image to fill the image view frame. Setting this parameter to the UIViewContentModeCenter will no longer be performed, but it will center the actual image.

0
source

In my case, I used my own subclass inherited from UITableViewCell . It is very clean and easy to use. In addition, I could use different image sizes to resize this cell well. The point is to use an additional property that will replace the regular imageView

1: In a subclass, I added the mainImageView property, which can be used instead of imageView .

 @property (nonatomic, retain) UIImageView *mainImageView; 

2: Then in - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier . I selected and initialized mainImageView . You can set any frame (straight line) for mainImageView . Add it as a subtitle to the contentView . I used insetImageView to align it vertically in the middle of the `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: override - (void)layoutSubviews to make sure other properties, such as textLabel , detailTextLabel , establish that their frames are well positioned with the mainImageView property 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: When using this cell in UITableDataSourceDelegate methods UITableDataSourceDelegate use cell.mainImageView to receive messages instead of the usual cell.imageView

0
source

Source: https://habr.com/ru/post/1338573/


All Articles