向UIView添加宽度边框显示外部的小背景

时间:2016-12-04 23:47:01

标签: ios swift uiview uikit xib

我尝试将绿色背景的圆圈边框添加到UIView,我创建了带有borderWidth,cornerRadius和borderColor属性的简单UIView子类,并且我从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

具有绿色背景,框架10x10,角半径= 5的RoundedView放置在普通UIImageView的角落(表示某人是否在线)。您可以在UIImageView和白色背景上看到外面的绿色边框。

enter image description here

你能告诉我出了什么问题吗?

4 个答案:

答案 0 :(得分:4)

您正在做的是依靠图层绘制边框并绕过角落。所以你不负责结果。你给它一个绿色背景,现在你看到背景“伸出”在边界的边缘。无论如何,圆角是一个非常笨拙和不可靠的方式来制作圆形视图。要制作圆形视图,请制作一个圆形的遮罩

因此,制作徽章的方法是完全掌控它的内容:白色的中心画一个绿色 背景,掩盖全部用一个较大的圆圈来制作边框。

这是一个徽章视图,它将完全按照您的要求进行操作,外部没有任何工件:

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)

看起来很好。根据需要调整参数。

答案 1 :(得分:1)

我通过使用UIBezierPath并添加到视图的图层来解决此问题:

        let strokePath = UIBezierPath(roundedRect: view.bounds, cornerRadius: view.frame.width / 2)
        let stroke = CAShapeLayer()
        stroke.frame = bounds
        stroke.path = strokePath.cgPath
        stroke.fillColor = .green.cgColor
        stroke.lineWidth = 1.0
        stroke.strokeColor = .white.cgColor
        view.layer.insertSublayer(stroke, at: 2)

答案 2 :(得分:0)

我用渐变解决了这个问题。 只需将圆的backgroundColor设置为渐变即可。

let gradientLayer = CAGradientLayer()
    //define colors
    gradientLayer.colors = [<<your_bgc_color>>>>,  <<border__bgc__color>>]
    //define locations of colors as NSNumbers in range from 0.0 to 1.0
    gradientLayer.locations = [0.0, 0.7]
    //define frame
    gradientLayer.frame = self.classView.bounds

    self.classView.layer.insertSublayer(gradientLayer, at: 0)

MyImage

答案 3 :(得分:0)

一个更简单的解决方法可能是像这样屏蔽它:

let mask = UIView()
mask.backgroundColor = .black
mask.frame = yourCircleView.bounds.inset(by: UIEdgeInsets(top: 0.1, left: 0.1, bottom: 0.1, right: 0.1))
mask.layer.cornerRadius = mask.height * 0.5
yourCircleView.mask = mask