2013-10-24 62 views
16

通過將cornerRadius應用於UIImageView的圖層,並通過borderWithborderColor添加邊框,我正在繪製圓形頭像圖片。像這樣:iOS:具有邊框出血顏色的圓角矩形

self.layer.masksToBounds = YES; 
self.layer.cornerRadius = imageDimension/2.f; 
self.layer.borderWidth = 1.f; 
self.layer.borderColor = borderColor.CGColor; 

,除了內容的這個小,但明顯的出血境外的偉大工程,是這樣的:

Content bleeding outside the mask and border

有沒有辦法,只是一開始就邊界由幾十分之一,還是插入的內容超過了邊界?


解決方案

感謝FelixLam,我想出了一個很好的解決方案,並會離開這裏爲後世:

@interface MMRoundImageViewWithBorder : UIView 

- (id)initWithImage:(UIImage *)image borderWidth:(CGFloat)borderWidth; 

@property (strong, nonatomic) UIImageView *imageView; 
@property (assign, nonatomic) CGFloat borderWidth; 
@property (strong, nonatomic) UIColor *borderColor; 

@end 

@implementation MMRoundImageViewWithBorder 

- (id)initWithImage:(UIImage *)image borderWidth:(CGFloat)borderWidth { 
    if (self = [super init]) { 
     self.borderWidth = borderWidth; 
     self.borderColor = UIColor.whiteColor; 

     self.imageView = [[UIImageView alloc] initWithImage:image]; 
     [self addSubview:self.imageView]; 

     self.imageView.layer.masksToBounds = YES; 
     self.layer.masksToBounds = YES; 
    } 
    return self; 
} 

- (void)setBorderColor:(UIColor *)borderColor { 
    _borderColor = borderColor; 
    self.backgroundColor = borderColor; 
} 

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    [self refreshDimensions]; 
} 

- (void)refreshDimensions { 
    self.layer.cornerRadius = CGRectGetWidth(self.bounds)/2.f; 

    self.imageView.frame = CGRectInset(self.bounds, _borderWidth, _borderWidth); 
    self.imageView.layer.cornerRadius = CGRectGetWidth(self.imageView.bounds)/2.f; 
} 

- (void)setBorderWidth:(CGFloat)borderWidth { 
    _borderWidth = borderWidth; 
    [self refreshDimensions]; 
} 

- (void)setFrame:(CGRect)frame { 
    [super setFrame:frame]; 
    [self refreshDimensions]; 
} 

@end 
+1

你可以嘗試透明的1個像素的邊框添加到您的圖像文件,所以你的形象將是2個像素寬和高,這應該與混合 – dariaa

回答

13

你可以嘗試使用CAShapelayer具有圓形路徑作爲圖層的蒙版,而不是使用圓角半徑。

或者,您可以將圖像視圖放置在具有邊框並且大一個/兩個像素的容器中。

+1

感謝您的想法幫助!我去了第二個選項,看起來不錯:) – manmal

-1

嘗試設置:

[self setClipToBounds:YES] 
+0

是不是'self.layer.masksToBounds = YES;' – FelixLam

+0

是啊。我試圖確定,沒有效果。 – manmal

1

正如評論所說,你可以在透明邊框添加到圖像,這將是確定。 下面是一段代碼,這樣做(一個類別的UIImageView):

+ (UIImage *)imageWithImage:(UIImage *)image withTransparentBorderOfWidth:(CGFloat)width { 
    CGSize size = image.size; 
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width + width * 2, size.height + width * 2), NO, 0.0); 
    [image drawInRect:CGRectMake(width, width, size.width, size.height)]; 
    image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return image; 
} 
+1

這是一個次優解決方案。如果從緩存中提取或刷新,則必須始終重新生成映像。在圖像周圍繪製邊框是IMO的渲染問題,而不是內容問題。 – manmal

+0

當然,它不乾淨。但它仍然在需要的情況下工作^^ – AncAinu

+0

當有9種方式到達目標時,不要選擇一個不好的方法。或者你的代碼庫很快就會腐爛。 – manmal

-1

我有同樣的問題和需要的解決方案,其將與故事板很好地工作。我所做的是將我的圖像放置在視圖中,然後將其設置爲控制行爲的自定義類。我現在可以完全控制故事板的設計。

我已將代碼放在GitHub上。

https://github.com/brennanMKE/CircleButton

它能做什麼是覆蓋的UIView的drawRect中功能都一個UIButton和普通的UIView,因此它可以與許多意見工作。包裝視圖也用於控制邊框的顏色和寬度。我只是確保在包裝視圖和超級視圖之間有一些邊距,並將差異用作邊框寬度。超級視圖的背景色成爲邊框顏色。現在,我可以在Storyboard中的許多場景中快速進行這些更改,而無需爲每個實例自定義編碼。

- (void)drawRect:(CGRect)rect { 
    // round view and superview with a border using the background color of the superview 
    self.layer.cornerRadius = CGRectGetWidth(self.frame)/2; 
    self.layer.masksToBounds = YES; 

    if ([self.superview isKindOfClass:[SSTCircleWrapperView class]]) { 
     self.superview.layer.cornerRadius = CGRectGetWidth(self.superview.frame)/2; 
     self.superview.layer.masksToBounds = YES; 
     self.superview.layer.borderColor = self.superview.backgroundColor.CGColor; 
     self.superview.layer.borderWidth = (CGRectGetWidth(self.superview.frame) - CGRectGetWidth(self.frame))/2; 
    } 
} 
+0

謝謝。我的解決方案是不是在故事板中工作(不是我真的很在意)?在兩個圖層上同時設置''''''''''''''''''''''''''''''''或者性能會大大降低。掩蔽似乎非常昂貴。 – manmal

+1

這是濫用繪製矩形,這些東西大部分應該只發生在框架改變時。 –

0

OP的解決方案不必要的複雜。更簡單,更乾淨的解決方案像上面創建一個UIView,剪輯到邊界,遮罩,邊框和角半徑,然後添加一個UIIamgeview作爲該UIView的子視圖。 UIIamgeview將被父視圖裁剪,您不會遇到流血問題。

0

我的UIButton需要一個圓角半徑導致鋸齒狀邊緣。設置borderStyle.roundedRect固定它。

button.borderStyle = .roundedRect 
button.layer.cornerRadius = 4 
button.layer.borderWidth = 1 
button.layer.borderColor = .red.cgColor