如何使用蒙版为圆形图像添加边框 [英] How to add a border to a circular image with mask
问题描述
这是我的尝试:
func round() {
let width = bounds.width < bounds.height ? bounds.width : bounds.height
let mask = CAShapeLayer()
mask.path = UIBezierPath(ovalInRect: CGRectMake(bounds.midX - width / 2, bounds.midY - width / 2, width, width)).CGPath
self.layer.mask = mask
// add border
let frameLayer = CAShapeLayer()
frameLayer.path = mask.path
frameLayer.lineWidth = 4.0
frameLayer.strokeColor = UIColor.whiteColor().CGColor
frameLayer.fillColor = nil
self.layer.addSublayer(frameLayer)
}
它适用于iphone 6模拟器(故事板大小为4.7),但在5s和6+上看起来很奇怪:
It works on the iphone 6 simulator (storyboard has size of 4.7), but on the 5s and 6+ it looks weird:
这是一个自动布局问题吗?没有边框,自动布局工作正常。这是我第一次使用面具,所以我不确定我所做的是否正确。
Is this an auto layout issue? Without the border, auto layout works correct. This is my first time working with masks and so I am not sure if what I have done is correct.
round
函数在 viewDidLayoutSubviews
中调用。
有什么想法?
推荐答案
如果你有子类 UIImageView
,例如,你可以覆盖 layoutSubviews
,以便它(a)更新掩码; (b)删除任何旧边界; (c)增加新的边界。在Swift 3中:
If you have subclassed UIImageView
, for example, you can override layoutSubviews
such that it (a) updates the mask; (b) removes any old border; and (c) adds a new border. In Swift 3:
import UIKit
@IBDesignable
class RoundedImageView: UIImageView {
/// saved rendition of border layer
private weak var borderLayer: CAShapeLayer?
override func layoutSubviews() {
super.layoutSubviews()
// create path
let width = min(bounds.width, bounds.height)
let path = UIBezierPath(arcCenter: CGPoint(x: bounds.midX, y: bounds.midY), radius: width / 2, startAngle: 0, endAngle: .pi * 2, clockwise: true)
// update mask and save for future reference
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
// create border layer
let frameLayer = CAShapeLayer()
frameLayer.path = path.cgPath
frameLayer.lineWidth = 32.0
frameLayer.strokeColor = UIColor.white.cgColor
frameLayer.fillColor = nil
// if we had previous border remove it, add new one, and save reference to new one
borderLayer?.removeFromSuperlayer()
layer.addSublayer(frameLayer)
borderLayer = frameLayer
}
}
这样,它会响应更改布局,但它确保清理任何旧边框。
That way, it responds to changing of the layout, but it makes sure to clean up any old borders.
顺便说一句,如果你不是子类 UIImageView
,而是将此逻辑放在视图控制器中,您将覆盖 viewWillLayoutSubviews
而不是 layoutSubviews
的UIView
。但基本的想法是一样的。
By the way, if you are not subclassing UIImageView
, but rather are putting this logic inside the view controller, you would override viewWillLayoutSubviews
instead of layoutSubviews
of UIView
. But the basic idea would be the same.
-
顺便说一下,我使用了一个面具与此形状图层结合使用,因为如果仅应用 UIView
的圆角,则可能会产生奇怪的伪影(在圆形边框的下半部分看到非常细的灰线) :
By the way, I use a mask in conjunction with this shape layer because if you merely apply rounded corners of a UIView
, it can result in weird artifacts (look at very thin gray line at lower part of the circular border):
如果使用bezier路径方法,则不会出现此类工件结果:
If you use the bezier path approach, no such artifacts result:
对于Swift 2.3示例,请参阅此答案的早期修订版。
For Swift 2.3 example, see earlier revision of this answer.
这篇关于如何使用蒙版为圆形图像添加边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!