向 UIView 添加带宽度的边框在外面显示小背景 [英] Adding border with width to UIView show small background outside

查看:25
本文介绍了向 UIView 添加带宽度的边框在外面显示小背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将圆形边框添加到具有绿色背景的 UIView 中,我创建了具有borderWidth、cornerRadius 和borderColor 属性的简单UIView 子类,并且我正在设置它从故事板.

I'm trying to add circle border to a UIView with green background, I created simple UIView subclass with borderWidth, cornerRadius and borderColor properties and I'm setting it from storyboard.

@IBDesignable
class RoundedView: UIView {

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable var borderColor: UIColor {
        get {
            if let color = layer.borderColor {
                return UIColor(cgColor: color)
            } else {
                return UIColor.clear
            }
        }
        set {
            layer.borderColor = newValue.cgColor
        }
    } 

}

但是当我编译并运行一个应用程序或在 InterfaceBuilder 中显示它时,我可以看到边界外的一条线仍然存在(并且在白色背景上非常明显).

But when I compile and run an app or display it in InterfaceBuilder I can see a line outside the border that is still there (and is quite visible on white background).

这个绿色背景的RoundedView,frame 10x10,corner radius = 5,放置在普通UIImageView的角落(表示是否有人在线).您可以在 UIImageView 和白色背景上看到外面的绿色边框.

This RoundedView with green background, frame 10x10, corner radius = 5 is placed in corner of plain UIImageView (indicates if someone is online or not). You can see green border outside on both UIImageView and white background.

你能告诉我有什么问题吗?

Can you please tell me what's wrong?

推荐答案

你所做的是依靠图层来绘制你的边框和圆角.所以你不负责结果.你给它一个绿色背景,现在你看到背景突出"在边框的边缘.无论如何,圆角是一种非常不可靠且不可靠的方式来制作圆形视图.要制作圆形视图,请制作圆形 蒙版.

What you are doing is relying on the layer to draw your border and round the corners. So you are not in charge of the result. You gave it a green background, and now you are seeing the background "stick out" at the edge of the border. And in any case, rounding the corners is a really skanky and unreliable way to make a round view. To make a round view, make a round mask.

因此,制作徽章的方法是完全掌控它所绘制的内容:白色的中心画一个绿色圆圈 背景,mask 用一个更大的圆圈来做边框.

So, the way to make your badge is to take complete charge of what it is drawn: you draw a green circle in the center of a white background, and mask it all with a larger circle to make the border.

这是一个徽章视图,可以精确地完成您所追求的工作,外部没有人工制品:

Here is a Badge view that will do precisely what you're after, with no artifact round the outside:

class Badge : UIView {
    class Mask : UIView {
        override init(frame:CGRect) {
            super.init(frame:frame)
            self.isOpaque = false
            self.backgroundColor = .clear
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        override func draw(_ rect: CGRect) {
            let con = UIGraphicsGetCurrentContext()!
            con.fillEllipse(in: CGRect(origin:.zero, size:rect.size))
        }
    }
    let innerColor : UIColor
    let outerColor : UIColor
    let innerRadius : CGFloat
    var madeMask = false
    init(frame:CGRect, innerColor:UIColor, outerColor:UIColor, innerRadius:CGFloat) {
        self.innerColor = innerColor
        self.outerColor = outerColor
        self.innerRadius = innerRadius
        super.init(frame:frame)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func draw(_ rect: CGRect) {
        let con = UIGraphicsGetCurrentContext()!
        con.setFillColor(outerColor.cgColor)
        con.fill(rect)
        con.setFillColor(innerColor.cgColor)
        con.fillEllipse(in: CGRect(
            x: rect.midX-innerRadius, y: rect.midY-innerRadius,
            width: 2*innerRadius, height: 2*innerRadius))
        if !self.madeMask {
            self.madeMask = true // do only once
            self.mask = Mask(frame:CGRect(origin:.zero, size:rect.size))
        }
    }
}

我尝试了如下示例设置:

I tried this with a sample setting as follows:

let v = Badge(frame: CGRect(x:100, y:100, width:16, height:16), 
              innerColor: .green, outerColor: .white, innerRadius: 5)
self.view.addSubview(v)

看起来不错.根据需要调整参数.

It looks fine. Adjust the parameters as desired.

这篇关于向 UIView 添加带宽度的边框在外面显示小背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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