Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS:带边框的圆形矩形出血颜色_Ios_Uiimageview_Calayer - Fatal编程技术网

iOS:带边框的圆形矩形出血颜色

iOS:带边框的圆形矩形出血颜色,ios,uiimageview,calayer,Ios,Uiimageview,Calayer,我正在绘制头像图片,只需将cornerRadius应用到UIImageView的图层,并通过borderWith和borderColor添加边框。像这样: self.layer.masksToBounds = YES; self.layer.cornerRadius = imageDimension / 2.f; self.layer.borderWidth = 1.f; self.layer.borderColor = borderColor.CGColor; 这非常有效,除了边界外的内容有

我正在绘制头像图片,只需将
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

您可以尝试使用带有圆形路径的
CAShapelayer
作为层的遮罩,而不是使用角半径

或者,您可以将图像视图放置在有边框且大一/两像素的容器中。

尝试设置:

[self setClipToBounds:YES]

正如在评论中所说,您可以向图像添加透明边框,这样就可以了。 下面是执行此操作的一段代码(UIImageView的一个类别):


我也有同样的问题,想要一个解决方案,可以很好地与故事板。我所做的是将图像放置在视图中,然后将两者设置为控制行为的自定义类。我现在可以完全从故事板控制设计

我已经把代码放在GitHub上了

它所做的是为UIButton和常规UIView覆盖UIView中的drawRect函数,以便可以处理多个视图。包装器视图还用于控制边框颜色和宽度。我只需确保包装视图和superview之间有一定的间距,并将其差值用作边框宽度。superview的背景色将成为边框颜色。现在,我可以在故事板中的许多场景中快速进行这些更改,而无需对每个实例进行自定义编码

- (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;
    }
}

OP的解决方案是不必要的复杂。更简单、更清洁的解决方案。创建UIView、剪裁到边界、遮罩、边界和角半径(如上所述),然后添加UIIAMGEEVIEW作为该UIView的子视图。UIIAMGEEVIEW将被父视图剪裁,您将不会有出血问题。

My
UIButton
需要圆角半径,这会导致锯齿状边缘。将
borderStyle
设置为
。roundedRect
修复了它

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

下面是解决此问题的
UIImageView
的子类

,它添加了一个圆角
CAShapeLayer
,其边框宽度和拐角半径比“想要的”大1倍。它的帧从
CGPoint(x:1,y:1)
开始,高度比图像视图的高度大2px。这样,它就覆盖了出血通道

Swift 3+解决方案 子类:

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()
用法:

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()
结果:

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()

您可以尝试在图像文件中添加一个透明的1像素边框,这样您的图像将更宽、更高2像素,这将有助于混合,因为这与
self.layer.masksToBounds=YES不同这是次优解决方案。如果从缓存中获取或刷新图像,则必须始终重新生成图像。在图像周围绘制边框是一个渲染问题,而不是内容问题。当有9种方法达到目标时,不要选择一种不好的方法。否则你的代码库很快就会腐烂。谢谢你的想法!我选择了第二个选项,看起来很棒:)谢谢。我的解决方案在故事板中不起作用吗(我真的不在乎)?另外,在两个层上都将
shoulldrasterize
设置为
YES
,否则性能将显著降低。屏蔽似乎非常昂贵。这是滥用draw rect,大多数这类事情应该只在帧发生变化时发生。嗯,这正是我的代码所做的,还是我忽略了什么?