ios - 向 UIView 添加带宽度的边框在外面显示小背景

标签 ios swift uiview uikit xib

我正在尝试将圆形边框添加到具有绿色背景的 UIView,我创建了简单的 UIView 子类,其中包含 borderWidth、cornerRadius 和 borderColor 属性,我正在设置它从 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 中显示它时,我可以看到边框外的一条线仍然存在(并且在白色背景上非常明显)。

enter image description here

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

enter image description here

你能告诉我哪里出了问题吗?

最佳答案

您正在做的是依靠图层来绘制边框和圆角。所以你不负责结果。你给它一个绿色的背景,现在你看到背景在边框的边缘“突出”。在任何情况下,圆角都是制作圆形 View 的一种非常卑鄙和不可靠的方式。要制作圆形 View ,请制作圆形 mask

因此,制作角标(Badge)的方法是完全控制绘制的内容:白色圆圈的中心绘制一个绿色 背景,并用一个更大的圆圈掩盖这一切来制作边框。

这是一个 Badge View ,它将完全按照您的要求进行操作,外部没有人工制品:

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

我尝试了以下示例设置:

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

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

关于ios - 向 UIView 添加带宽度的边框在外面显示小背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40965120/

相关文章:

ios - 如何在 iPhone 中使用图像和标签在 Mapview 中添加注释?

ios - 通过 CloudKit 打开共享文档时出错

ios - 如何在将数据添加到数据库后立即从 Core Data 中获取数据

iphone - 如何动态设置UIScrollView的内容大小

ios - 试图在其 super View 中居中 View

ios - 当我将一个 View 添加到另一个 View 时(这两个 View 都由 View Controller 控制),我真的应该使用 addChildViewController 吗?

ios - 如何将 Hstack 内部的 View 与相对侧对齐?

ios - Swift 2.1 - 删除单元格后清除 TableViewCell 中的文本字段

IOS 13 : spacing Issue with UITextField rightView

ios - CollectionView Flowlayout自定义