이미지가 작아도 UITableViewCell의 이미지 보기를 고정 크기로 만드는 방법
셀의 이미지 보기에 사용하는 이미지가 여러 개 있습니다. 모두 50x50 이하입니다(예: 40x50, 50x32, 20x37...).
테이블 보기를 로드하면 이미지 너비가 달라 텍스트가 줄을 서지 않습니다.또한 왼쪽이 아닌 중앙에 작은 이미지가 나타나길 원합니다.
여기 제 'CellForRowAt' 안에서 시도 중인 코드가 있습니다.IndexPath' 메서드
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];
보시다시피 저는 몇 가지 시도를 해보았지만 어느 것도 효과가 없습니다.
모든 것을 다시 쓸 필요는 없습니다.대신 이 작업을 수행하는 것이 좋습니다.
이것을 사용자 지정 셀의 .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;
}
위의 코드는 크기를 40x40으로 설정합니다.
스위프트 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;
}
스위프트 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;
}
이미지 보기:표 보기 셀에 하위 보기로 추가
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의 Width 속성입니다.그런 다음 셀 왼쪽에 사용자 정의 imageView를 추가합니다.
이미지 보기를 만들어 셀에 하위 보기로 추가하는 것이 좋습니다.그러면 원하는 프레임 크기를 얻을 수 있습니다.
심플리 스위프트,
1단계: 하나의 하위 클래스 만들기UITableViewCell
2단계: 이 메서드를 UITableViewCell의 SubClass에 추가합니다.
override func layoutSubviews() {
super.layoutSubviews()
self.imageView?.frame = CGRectMake(0, 0, 10, 10)
}
3단계: 에서 해당 SubClass를 사용하여 셀 객체를 만듭니다.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;
}
@German Attanasio의 답변을 사용하여 확장을 만들었습니다.이미지 크기를 원하는 크기로 조정하는 방법과 투명 여백을 이미지에 추가하는 다른 방법을 제공합니다(이 방법은 이미지에 여백을 두려는 테이블 뷰에도 유용할 수 있습니다).
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의 하위 클래스를 만듭니다(스토리지보드에서 셀을 연결해야 함).
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)
}
}
}
행에 대한 셀내IndexPath, 새 셀 유형으로 셀 대기열 해제:
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyTableCell
레이아웃에 맞게 숫자 값을 분명히 변경합니다.
스위프트 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에 제약 조건을 설정할 수 있습니다.여기 제가 프로젝트에서 사용한 작업 사례가 있습니다.하위 분류를 피하고 프로토타입 셀로 스토리보드를 만들 필요가 없었지만 실행하는 데 상당한 시간이 걸렸기 때문에 더 단순하거나 간결한 방법이 없는 경우에만 사용하는 것이 가장 좋습니다.
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
}
저도 같은 문제가 있었습니다.답변해주신 다른 모든 분들께 감사드립니다. 저는 이 답변들 중 일부를 사용하여 함께 해결책을 얻을 수 있었습니다.
나의 해결책은 swift 5를 사용하는 것입니다.
우리가 해결하려고 하는 문제는 우리의 화면에 다른 가로 세로 비율을 가진 이미지가 있을 수 있다는 것입니다.TableViewCell
하지만 우리는 그들이 일관된 폭으로 렌더링하기를 원합니다.물론 이미지는 왜곡 없이 렌더링되고 전체 공간을 채워야 합니다.저의 경우, 저는 키가 크고 마른 이미지의 "자르기"가 괜찮았기 때문에 컨텐츠 모드를 사용했습니다..scaleAspectFill
이를 위해 다음의 사용자 정의 하위 클래스를 만들었습니다.UITableViewCell
저 같은 경우에는 이름을 지었습니다.StoryTableViewCell
전체 클래스는 아래에 설명이 줄을 지어 붙여넣습니다.
이 접근 방식은 사용자 지정 액세서리 보기 및 긴 텍스트 레이블을 사용할 때도 효과적이었습니다.다음은 최종 결과의 이미지입니다.
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;
}
}
}
일반 UITableViewCell은 물건을 배치하는 데 잘 작동하지만 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에서 수행할 것으로 예상되는 작업이 작업은 UIImageView에서 수행됩니다.당신이 주는 이미지와 상관없이 당신이 원하는 사이즈가 되세요.이것은 테이블View: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();
우리가 얻은 해결책은 다른 많은 해결책들과 유사합니다.하지만 분리기의 정확한 위치를 얻기 위해 우리는 전화하기 전에 그것을 설정해야 했습니다.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)
}
}
언급URL : https://stackoverflow.com/questions/2788028/how-do-i-make-uitableviewcells-imageview-a-fixed-size-even-when-the-image-is-sm
'programing' 카테고리의 다른 글
소수 자릿수 형식 지정(R) (0) | 2023.06.05 |
---|---|
장고 모델에서 목록을 저장하는 가장 효율적인 방법은 무엇입니까? (0) | 2023.06.05 |
미학 및 gem_text를 사용할 때 범례에서 'a' 제거 (0) | 2023.06.05 |
R을 사용하여 압축된 데이터 파일 다운로드, 압축 풀기 및 데이터 가져오기 (0) | 2023.06.05 |
괄호 안의 문자열은 왜 그 문자열만으로 튜플을 만들지 않습니까? (0) | 2023.06.05 |