l30c0d35
l30c0d35

Reputation: 807

Swift: UIVisualEffectView with rounded top edges and colored border

I am trying to setup a view with rounded corners but only the top left and right corner and with a colored border. This is my views class:

class PullUpOverview: UIVisualEffectView {

override init(effect: UIVisualEffect?) {
    super.init(effect: effect)

    let maskLayer = CAShapeLayer()
    maskLayer.path = UIBezierPath(roundedRect: bounds,
                                  byRoundingCorners: [.topRight, .topLeft],
                                  cornerRadii: CGSize(width: 25, height: 25)).cgPath
    layer.mask = maskLayer

    let borderLayer = CAShapeLayer()
    borderLayer.frame = bounds
    borderLayer.path = maskLayer.path
    borderLayer.lineWidth = 1
    borderLayer.strokeColor = UIColor.gray.cgColor
    borderLayer.fillColor = UIColor.clear.cgColor
    layer.addSublayer(borderLayer)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

I add the view to my viewController view in the viewDidLoad method like this (overviewRect is correctly setup):

let overview = PullUpOverview(effect: UIBlurEffect(style: UIBlurEffect.Style.extraLight))
overview.frame = overviewRect
self.mapView.addSubview(overview)

But if I add the view nothing appears. If I change the PullUpOverview's super class to UIView and change my code in the viewDidLoad method to following the view and its mask is added and applied correctly (obviously the blur effect is missing that's why I tried to do the same with and UIVisualEffectView):

let overview = PullUpOverview(frame: overviewRect)
self.mapView.addSubview(overview)

So what do I have to change that I get an UIVisualEffectView with two rounded corners (both top corners) and a border layer?

Upvotes: 2

Views: 512

Answers (1)

Kamran
Kamran

Reputation: 15258

The size is zero for bounds so both layers can not be visible. You can introduce a custom initializer as below,

class PullUpOverview: UIVisualEffectView {

    init(effect: UIVisualEffect?, size: CGSize) {
        super.init(effect: effect)

        let rect = CGRect(origin: .zero, size: size)

        let maskLayer = CAShapeLayer()
        maskLayer.path = UIBezierPath(roundedRect: rect,
                                      byRoundingCorners: [.topRight, .topLeft],
                                      cornerRadii: CGSize(width: 25, height: 25)).cgPath
        maskLayer.frame = rect
        layer.mask = maskLayer

        let borderLayer = CAShapeLayer()
        borderLayer.frame = rect
        borderLayer.path = maskLayer.path
        borderLayer.lineWidth = 1
        borderLayer.strokeColor = UIColor.yellow.cgColor
        borderLayer.fillColor = UIColor.clear.cgColor
        layer.addSublayer(borderLayer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

And now you can initialize and add this view as,

let overviewRect = CGRect(origin: CGPoint(x: 100, y: 200), size: CGSize(width: 200, height: 200))
let overview = PullUpOverview(effect: UIBlurEffect(style: .dark), size: overviewRect.size)
overview.frame = overviewRect
self.view.addSubview(overview)

This will result into following,

enter image description here

Upvotes: 1

Related Questions