我正在绘制头像图片,只需将cornerRadius
应用于UIImageView
的图层,并通过borderWith
和borderColor
添加边框。像这样:
self.layer.masksToBounds = YES;
self.layer.cornerRadius = imageDimension / 2.f;
self.layer.borderWidth = 1.f;
self.layer.borderColor = borderColor.CGColor;
这种方法很有效,除了边界外的这种微小但明显的内容出血,如下:
有没有办法让边界开始几个1/10点,或者将内容多于边界?
感谢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
答案 0 :(得分:14)
您可以尝试使用带有圆形路径的CAShapelayer
作为图层的蒙版,而不是使用圆角半径。
或者,您可以将图像视图放在具有边框并且大一个/两个像素的容器中。
答案 1 :(得分: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;
}
答案 2 :(得分:0)
答案 3 :(得分:0)
我的UIButton
需要圆角半径,导致锯齿状边缘。将borderStyle
设为.roundedRect
修正了它。
button.borderStyle = .roundedRect
button.layer.cornerRadius = 4
button.layer.borderWidth = 1
button.layer.borderColor = .red.cgColor
答案 4 :(得分:0)
这是UIImageView
的子类,可以解决此问题。
As the accepted answer suggests,它添加了一个圆形的CAShapeLayer
,该边框的宽度和转角半径比“所需”大1px。其框架始于CGPoint(x: 1, y: 1)
,其高度比图像视图的高度大2px。这样,它涵盖了渗漏。
子类:
class BorderedRoundedImageView: UIImageView {
let borderLayer = CALayer()
var borderWidth: CGFloat!
var borderColor: UIColor!
func setUp() {
borderLayer.borderWidth = borderWidth + 1
borderLayer.borderColor = borderColor.cgColor
layer.addSublayer(borderLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
borderLayer.cornerRadius = layer.cornerRadius + 1
borderLayer.frame = CGRect(x: -1, y: -1, width: frame.width + 2, height: frame.height + 2)
}
}
用法:
@IBOutlet weak var imageView: UIImageView!
[...]
imageView.layer.cornerRadius = 20
imageView.borderWidth = 2
imageView.borderColor = .lightGray
imageView.setUp()
结果:
答案 5 :(得分:-1)
尝试设置:
[self setClipToBounds:YES]
答案 6 :(得分:-1)
我遇到了同样的问题,想要一个适用于Storyboard的解决方案。我所做的是将我的图像放在视图中,然后将它们都设置为控制行为的自定义类。我现在可以从故事板中完全控制设计。
我已将代码放在GitHub上。
https://github.com/brennanMKE/CircleButton
它的作用是覆盖UIView中的drawRect函数,用于UIButton和常规UIView,因此它可以处理许多视图。包装器视图还用于控制边框颜色和宽度。我只是确保包装视图和超视图之间有一些边距,并使用差异作为边框宽度。 superview的背景颜色成为边框颜色。现在,我可以在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;
}
}