如何使用蒙版为圆形图像添加边框 [英] How to add a border to a circular image with mask

查看:178
本文介绍了如何使用蒙版为圆形图像添加边框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的尝试:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆