모든 UIImageView에 둥근 모서리 추가


78

내 프로젝트의 모든 UIImageView에 둥근 모서리를 추가하고 싶습니다. 이미 코드가 작동하고 있지만 모든 이미지에 적용해야합니다. 이것을 추가하려면 UIImageView를 하위 클래스로 만들어야합니까? 그렇다면 누군가가 이것을 수행하는 방법에 대한 몇 가지 지침을 줄 수 있습니까?

다음은 코드입니다.

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *mainpath = [[NSBundle mainBundle] bundlePath];
    welcomeImageView.image = [UIImage imageWithContentsOfFile:[mainpath stringByAppendingString:@"/test.png"]];
    welcomeImageView.layer.cornerRadius = 9.0;
    welcomeImageView.layer.masksToBounds = YES;
    welcomeImageView.layer.borderColor = [UIColor blackColor].CGColor;
    welcomeImageView.layer.borderWidth = 3.0;
    CGRect frame = welcomeImageView.frame;
    frame.size.width = 100;
    frame.size.height = 100;
    welcomeImageView.frame = frame;
}

안녕 잭-감사합니다. 바로 제가하고 싶었던 일입니다. 이것을 사용하려고하면 '알 수없는 속성의'cornerRadius '구성 요소에 액세스하는 중'오류가 발생하고 masksToBounds 등에 대해서도 동일합니다. 이상하게도 xcode의 코드 감지 기능이 이러한 속성을 유용하게 채우지 만 컴파일러는 그렇지 않습니다. 컴파일하십시오. 위의 코드가 iOS4.0에서 작동합니까?
Ben Clayton

20
당신은 필요에 # import를 <QuartzCore / QuartzCore.h>
vodkhang

답변:


25

클래스를 하위 클래스로 만드는 대체 방법 인 UIImage에 대한 카테고리를 사용할 수 있으며 때로는 작은 변경에 더 쉽게 적용 할 수 있습니다.

예를 들어 둥근 모서리 속성이 설정된 UIImage를 반환하는 메서드를 추가합니다.

+(UIImage *)imageWithContentsOfFile:(NSString *)file cornerRadius:(NSInteger)... 

Objective-c 카테고리에 대한 자세한 정보는 http://macdevelopertips.com/objective-c/objective-c-categories.html 에서 찾을 수 있습니다 .


우수한. 감사합니다. UIImage 카테고리를 구현할 것입니다. macdevelopertips.com에있는 튜토리얼은 매우 유용합니다.
Jack

4
하위 클래스를 만드는 방법을 설명하려고했지만이 접근 방식이 훨씬 더 마음에 듭니다.
Kendall Helmstetter Gelner

의아해합니다. 따라서 모든 UIImage의 100 %가 이것을 갖게됩니다. UIFramedImage와 같은 하위 클래스 UIImage가 아닌 이유는 무엇입니까?
Rob

1
다음은 위의 방법에 대한 링크입니다. igframework-iphone-static-library-project.googlecode.com/…
Bobj-C

3
@Rob 실제로이 접근 방식을 사용하면 UIImage의 0 %는 새 메서드를 호출하도록 변경할 때까지 둥근 모서리를 갖게됩니다. 이 솔루션은 기존 메서드를 재정의하지 않습니다 (이렇게하면 안 됨). 전체 하위 클래스가 필요하지 않기 때문에 하위 클래스보다 더 깔끔한 솔루션이 될 수 있습니다. UIImage에 멤버 나 새 기능을 추가하지 않기 때문에 과도 할 수 있습니다. 원하는 것은 코드 중복이없는 UIImage 둥근 모서리뿐입니다.
Jarsen 2013

114

이것을 확인하십시오 -UIImage의 둥근 모서리

레이어 수정이 가장 좋은 방법 인 것 같습니다.

UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]];
// Get the Layer of any view
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];

1
감사. 이것은 본질적으로 내가 이미 한 일이지만, 점 표기법을 사용하여 속성을 변경했습니다. 반경을 변경하려는 경우 모든 인스턴스를 변경할 필요가 없도록 하위 클래스에 추가하는 것이 쉬운 지 궁금했습니다.
Jack

-1 이것은 각 UIImageView인스턴스에 동일한 코드를 쉽게 적용하는 질문에 대한 대답을 시도하지 않습니다 .
Stuart

16

서브 클래 싱 대신 UIImageView 및 CALayer의 간단한 카테고리를 통해 더 강력한 기능을 얻을 수 있습니다.

다음과 같이 UIImageView에 범주를 만듭니다.

- (void)maskRoundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
    // To round all corners, we can just set the radius on the layer
    if ( corners == UIRectCornerAllCorners ) {
        self.layer.cornerRadius = radius;
        self.layer.masksToBounds = YES;
    } else {
        // If we want to choose which corners we want to mask then
        // it is necessary to create a mask layer.
        self.layer.mask = [CALayer maskLayerWithCorners:corners radii:CGSizeMake(radius, radius) frame:self.bounds];
    }
}

CALayer에서 카테고리 메소드를 호출합니다.

+ (id)maskLayerWithCorners:(UIRectCorner)corners radii:(CGSize)radii frame:(CGRect)frame {

    // Create a CAShapeLayer
    CAShapeLayer *mask = [CAShapeLayer layer];

    // Set the frame
    mask.frame = frame;

    // Set the CGPath from a UIBezierPath
    mask.path = [UIBezierPath bezierPathWithRoundedRect:mask.bounds byRoundingCorners:corners cornerRadii:radii].CGPath;

    // Set the fill color
    mask.fillColor = [UIColor whiteColor].CGColor;

    return mask;
}

따라서 UIRectCorner모서리의 모든 조합 (참조 ) 을 둥글게 할 수 있습니다 UITableView. 그룹 스타일에 이미지를 넣을 때 특히 유용합니다 . 그러나이 작업을 수행 할 때 한 가지주의 사항이 있습니다. 서브 클래 싱하지 않았기 때문에에 UIImageView코드를 삽입 할 수 없습니다. layoutSubviews즉, 마스크 레이어가 올바르지 않을 수 있습니다. 실제로 셀을 구성 할 때 category 메서드를 호출 할 때 이미지보기의 경계가 설정되지 않습니다. 따라서 둥근 모서리를 추가하기 전에 이미지 뷰의 경계가 설정되었는지 확인해야합니다 (를 사용하는 경우 제외 UIRectCornersAllCorners).

다음은이를 수행하는 코드입니다.

        // Perform corner rounding
        UIRectCorner corners = !UIRectCornerAllCorners;
        if (indexPath.row == 0) 
            corners = UIRectCornerTopLeft;
        if (indexPath.row == numberOfRowsInTheTable)  
            corners |= UIRectCornerBottomLeft;

        if (corners > 0) {
            cell.imageView.bounds = CGRectMake(0.f, 0.f, [self.tableView rowHeight], [self.tableView rowHeight]);
            [cell.imageView maskRoundCorners:corners radius:10.f];
        } else {
            [cell.imageView removeRoundCornersMask];
        }

둥근 모서리를 제거하는 또 다른 범주가 있습니다. 모든 작업은 마스크를 제거하고 cornerRadius를 0으로 설정하는 것입니다.


1
훌륭한 솔루션. 하지만 모든 뷰가 UILabel, UIButton, UIView 등과 같이 액세스 할 수있는 클래스를 만드는 것이 더 낫지 않은지 궁금합니다. 일종의 범용 메서드입니까?
Borut Tomazin

1
신경 쓰지 마. 모든 종류의 뷰를 처리하는 UIView 범주를 방금 만들었습니다. 감사!
Borut Tomazin

1
@BorutTomazin 대단한 생각-YAGNI를 생각하고 있었지만 UIImageView 카테고리를 UIView로 옮기는 것은 훌륭한 작은 유틸리티 기능이 될 것입니다.
Daniel Thorpe

1
정확히 내가 한 일. 이제 부모가 UIView라는 모든 뷰에서 사용할 수 있습니다 ...
Borut Tomazin

5

예, UIImageView를 하위 클래스로 만들고 프로젝트 전체에서 사용자 정의 하위 클래스를 사용해야합니다.


1
감사합니다. 그게 최선의 방법이라고 생각했습니다. 서브 클래스 사용에 대한 좋은 튜토리얼을 알고 있습니까? 이 방법을 인터페이스 빌더와 함께 사용할 수 있습니까? 아니면 코드에서 인터페이스를 다시 작성해야합니까?
Jack

2
사실, 위의 Martinj의 대답은 등 인터페이스 빌더에서, 어디서나 사용자 정의 서브 클래스를 사용할 필요에서 당신을 저장하는 것이 더 쉬울 것입니다
야콥 보그

4

UIImageView를 하위 클래스로 만들 수 있으며 setNeedsDisplay 메서드 를 구현 하면 둥근 모서리가 하위 클래스에서 작동합니다. (QuartzCore를 가져 오는 것을 잊지 마십시오)

-(void)setNeedsDisplay {
    self.layer.cornerRadius = 5;
    self.layer.masksToBounds = YES;
    [self.layer setBorderColor:[[UIColor whiteColor] CGColor]];
    [self.layer setBorderWidth: 2.0];
}

3
이 작업을 수행해서는 안되며 setNeedsDisplay는 기본적으로 다시 그리기를 예약하며 그게 목적입니다. init 메소드에서 레이어를 설정해야합니다.
Ben Affleck

3

이 시도,

coverImage.image = [UIImage imageWithContentsOfFile:@"coverImage.png"]; 
coverImage.layer.masksToBounds = YES;
coverImage.layer.cornerRadius = 10.0;
coverImage.layer.borderWidth = 1.0;
coverImage.layer.borderColor = [[UIColor brown] CGColor];

이것은 당신을 도울 수 있습니다.


-1 이것은 질문에 대한 대답을 시도하지 않습니다. 문제는 반올림을 생성하는 방법 UIImageView(질문의 코드 스 니펫에서 성공적으로 수행됨)이 아니라 해당 코드를 효과적으로 재사용하는 방법에 관한 것입니다.
Stuart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.