UIButton의 이미지를 AspectFit으로 조정 하시겠습니까?


94

UIButton에 이미지를 추가하고 UIButton에 맞게 이미지 크기를 조정하고 싶습니다 (이미지를 더 작게 만들기). 어떻게하는지 보여주세요.

이것은 내가 시도한 것이지만 작동하지 않습니다.

  • 버튼에 이미지 추가 및 사용 setContentMode:
[self.itemImageButton setImage:stretchImage forState:UIControlStateNormal];
[self.itemImageButton setContentMode:UIViewContentModeScaleAspectFit];
  • "이미지 늘이기"만들기 :
UIImage *stretchImage = [updatedItem.thumbnail stretchableImageWithLeftCapWidth:0 topCapHeight:0];

펌웨어 4.0 이상에서는 이것이 기본 동작으로 변경되었다고 생각합니다.
Shaun Budhram

1
솔루션 은 stackoverflow.com/a/28205566/481207 을 참조하십시오 .
매트

답변:


28

정말로 이미지의 크기를 조절하고 싶다면 그렇게하되 사용하기 전에 크기를 조절해야합니다. 런타임에 크기를 조정하면 CPU 주기만 손실됩니다.

이것은 이미지 크기를 조정하는 데 사용하는 카테고리입니다.

UIImage + Extra.h

@interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
@end;

UIImage + Extra.m

@implementation UIImage (Extras)

- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {

UIImage *sourceImage = self;
UIImage *newImage = nil;

CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;

CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;

CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;

CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

if (!CGSizeEqualToSize(imageSize, targetSize)) {

        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor < heightFactor) 
                scaleFactor = widthFactor;
        else
                scaleFactor = heightFactor;

        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the image

        if (widthFactor < heightFactor) {
                thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
        } else if (widthFactor > heightFactor) {
                thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
}


// this is actually the interesting part:

UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0);

CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width  = scaledWidth;
thumbnailRect.size.height = scaledHeight;

[sourceImage drawInRect:thumbnailRect];

newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

if(newImage == nil) NSLog(@"could not scale image");


return newImage ;
}

@end

원하는 크기로 사용하실 수 있습니다. 처럼 :

[self.itemImageButton setImage:[stretchImage imageByScalingProportionallyToSize:CGSizeMake(20,20)]];

답변 해 주셔서 감사합니다, Gcamp. 비율로 크기를 조정하는 방법이 있습니다. 그러나 나는 여전히 UIButton에게 나를 위해 그것을 지시하는 방법을 찾으려고 노력하고 있습니다. 내 이미지는 인터넷에서로드되어 컴파일 타임에 크기를 조정할 수 없습니다. BTW, 귀하의 답변에 감사드립니다.
KONG

2
이미지가 CALayer에 배치되고 Quartz에 의해 렌더링되고 캐시되기 때문에 전체 크기로 배치해도 성능이 더 나 빠지지 않습니다. 어느 쪽이든, ~ 1 번 크기를 조정합니다. 버튼의 크기를 지속적으로 조정하거나 Quartz가 이미지 레이어를 다시 그리도록 트리거하는 다른 작업을 수행하는 경우 gcamp의 대답이 훨씬 더 중요합니다.
Ben Gotow

화질이 저하 된 것 같습니다. 나는 아이폰 6 플러스에서 테스트 중입니다. 사실인가요? 3x 이미지도 있습니다.
Khant Thu Linn

예,이 코드는 꽤 오래되었습니다. 그것은이었다 UIGraphicsBeginImageContext대신 UIGraphicsBeginImageContextWithOptions. 방금 고쳤습니다.
gcamp

그래하지만 많은 경우에 당신은 몇 사이클을 풀어 문제가되지 않는 경우 램 채우고에서 어떤 점 때문에
라두 Simionescu

203

나는 같은 문제가 있었다. UIButton 안에있는 ImageView의 ContentMode를 설정하기 만하면됩니다.

[[self.itemImageButton imageView] setContentMode: UIViewContentModeScaleAspectFit];
[self.itemImageButton setImage:[UIImage imageNamed:stretchImage] forState:UIControlStateNormal];

도움이 되었기를 바랍니다.


14
imageView를 설정하고 있는지 확인하십시오 . 나는 또한 backgroundImageView를 여전히 사용하고 있고 그것이 작동하지 않는다는 것을 조금 눈치 채지 못했습니다.
Alexandre Gomes

2
이 방법은 버튼 상태가 '강조 표시'일 때 몇 가지 문제가있는 것 같습니다. 이미지가 채우기 모드로 돌아갑니다. 어떤 생각?
Yuanfei Zhu 2012

나에게 효과가 없습니다. 그러나 [self.itemImageButton setbackgroundImage : [UIImage imageNamed : stretchImage] forState : UIControlStateNormal]을 사용하여 작동합니다.
Mickey

3
이것은 나를 위해 일했습니다. 위와 같이 콘텐츠 모드를 설정했습니다. 그러나 이미지가 "채우기 모드"로 돌아가는 것을 방지하려면 강조 표시된 상태의 동일한 이미지를 설정해야합니다. 예 : [imageButton setImage : image forState : UIControlStateHighlighted];
크리스토퍼

1
Interface Builder에서 키 경로 imageView.contentMode, 유형 Number및 값 으로이 작업을 수행 할 수 있습니다.1
bendytree 2015

107

여기에 대한 답변 중 어느 것도 나를 위해 실제로 효과가 없었으며 다음 코드로 문제를 해결했습니다.

button.contentMode = UIViewContentModeScaleToFill;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

Interface Builder에서도이 작업을 수행 할 수 있습니다.

여기에 이미지 설명 입력


5
이것은 OP에서 요청한대로 aspect fit 동작을 제공하지 않습니다 .
Ortwin Gentz

3
@OrtwinGentz Aspect fit대신 모드를 선택하고 설정할 수 있습니다 scale to fill.
Daniel

55

가로 세로 맞춤 모드 에서 프로그래밍 방식으로 UIButton imageView를 설정하는 가장 쉬운 방법 :

빠른

button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageView?.contentMode = .scaleAspectFit

목표 -C

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
button.imageView.contentMode = UIViewContentModeScaleAspectFit;

참고 : .scaleAspectFit (UIViewContentModeScaleAspectFit)를 .scaleAspectFill (UIViewContentModeScaleAspectFill)로 변경하여 종횡비 채우기 모드 를 설정할 수 있습니다.


20

이미지의 크기가 비례 적으로 조정되지 않는 문제가 있었기 때문에 수정 한 방식은 가장자리 삽입을 사용하는 것이 었습니다.

fooButton.contentEdgeInsets = UIEdgeInsetsMake(10, 15, 10, 15);

16

이제 IB의 UIButton 속성을 통해이 작업을 수행 할 수 있습니다. 핵심은 이미지를 배경으로 설정하는 것입니다. 그렇지 않으면 작동하지 않습니다.

여기에 이미지 설명 입력


14

Dave의 답변을 확장 하면 런타임 속성을 사용하여 코드없이 IB에서 contentMode버튼의 imageView전체를 설정할 수 있습니다 .

여기에 이미지 설명 입력

  • 1의미 UIViewContentModeScaleAspectFit,
  • 2의미 UIViewContentModeScaleAspectFill합니다.

8

버튼 이미지를 줄이려면 :

yourButton.contentMode = UIViewContentModeScaleAspectFit;
yourButton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);

yourButton.imageView.contentMode = UIViewContentModeScaleAspectFit이어야합니다.
sdsykes

.imageView로 시도하지 않았습니다. 꽤 잘 작동하지 않습니다.
Tulleb

5

1-버튼 기본 텍스트 지우기 (중요)

2-이미지와 같은 정렬 설정

3-이미지와 같은 콘텐츠 모드 설정

여기에 이미지 설명 입력


좋은 대답 형제 .. 나를 많이 도왔습니다. 감사!
BharathRao

5

나를 위해 그것을하는 방법이 있습니다. 이 방법은 UIButton이미지 측면을 취하고 적합하게 만듭니다.

-(void)makeImageAspectFitForButton:(UIButton*)button{
    button.imageView.contentMode=UIViewContentModeScaleAspectFit;
    button.contentHorizontalAlignment=UIControlContentHorizontalAlignmentFill;
    button.contentVerticalAlignment=UIControlContentVerticalAlignmentFill;
}

4

가장 깨끗한 해결책은 자동 레이아웃 을 사용하는 것 입니다. 내 콘텐츠 압축 저항 우선 순위 를 낮추고 인터페이스 빌더 를 통해 UIButton이미지 ( 배경 이미지 아님)를 설정했습니다 . 그 후 버튼의 크기를 정의하는 몇 가지 제약 조건 (제 경우에는 상당히 복잡함)을 추가했으며 매력처럼 작동했습니다.


이것은 나를 위해 일했지만 실제 이미지가 아닌 "배경 이미지"를 사용하도록 선택한 경우에만 작동했습니다. 뭐든간에! 이것은 나에게 NUTS를 운전했다.
Andy

Xcode 6.2에서 이것은 나를 위해 일했지만 @AndrewHeinlein이 말했듯이 사용Background Image
RoLYroLLs

3

이미지를 배경이 아닌 이미지 속성으로 설정했는지 확인하십시오.


2

배경 이미지는 실제로 가로 세로 채우기를 매우 쉽게 조정하도록 설정할 수 있습니다. UIButton의 하위 클래스에서 다음과 같은 작업을 수행하면됩니다.

- (CGRect)backgroundRectForBounds:(CGRect)bounds
{
    // you'll need the original size of the image, you 
    // can save it from setBackgroundImage:forControlState
    return CGRectFitToFillRect(__original_image_frame_size__, bounds);
}

// Utility function, can be saved elsewhere
CGRect CGRectFitToFillRect( CGRect inRect, CGRect maxRect )
{
    CGFloat origRes = inRect.size.width / inRect.size.height;
    CGFloat newRes = maxRect.size.width / maxRect.size.height;

    CGRect retRect = maxRect;

    if (newRes < origRes)
    {
        retRect.size.width = inRect.size.width * maxRect.size.height / inRect.size.height;
        retRect.origin.x = roundf((maxRect.size.width - retRect.size.width) / 2);
    }
    else
    {
        retRect.size.height = inRect.size.height * maxRect.size.width / inRect.size.width;
        retRect.origin.y = roundf((maxRect.size.height - retRect.size.height) / 2);
    }

    return retRect;
}

서브 클래스 없이는 가능하지 않습니까?
Iulian Onofrei

이 답변은 특히 backgroundImage에 대한 것입니다. 메인 이미지의 경우 imageEdgeInsets로 원숭이를 만들 수 있습니다.
Andy Poes

나는 알고 있고, 서브 클래스없이 이것을 달성 할 수 있다면 원했다.
Iulian Onofrei

내가 아는 한, 서브 클래 싱없이 backgroundImage를 조정할 수 없습니다.
Andy Poes 2017

1

스위프트 5.0

 myButton2.contentMode = .scaleAspectFit
 myButton2.contentHorizontalAlignment = .fill
 myButton2.contentVerticalAlignment = .fill

0

Xamarin.iOS (C #)의 경우 :

    myButton.VerticalAlignment = UIControlContentVerticalAlignment.Fill;
    myButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
    myButton.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;

-1

세 가지 이벤트에 대해 UIButton imageview의 콘텐츠 모드를 설정하기 만하면됩니다. -

[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];

[cell.button setImage:[UIImage imageWithData:data] forState:UIControlStateHighlighted];

[cell.imgIcon setImage:[UIImage imageWithData:data] forState:UIControlStateSelected];

버튼 크기가 SQUARE이고 이미지 크기가 직사각형인지 강조 표시하거나 선택하는 동안 세 가지 이벤트 bcoz에 대한 코드가 있으며 강조 표시 또는 선택시 정사각형 이미지가 표시됩니다.

나는 그것이 당신을 위해 일할 것이라고 확신합니다.


콘텐츠 모드를 설정하는 것이 아니라 이미지를 설정하는 것입니다. 그리고 그들은 사건이 아니라 국가입니다. 당신은 큰 혼란을 만들고 있습니다. 이것은 질문과는 전혀 관련이 없습니다.
manecosta
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.