Skip to content

Instantly share code, notes, and snippets.

@RamonGilabert
Last active August 26, 2020 12:05
Show Gist options
  • Save RamonGilabert/2d77e45473aad671df0a499fdd168d07 to your computer and use it in GitHub Desktop.
Save RamonGilabert/2d77e45473aad671df0a499fdd168d07 to your computer and use it in GitHub Desktop.
import UIKit
class Squircle: UIView {
private var radius: CGFloat = 0
private var smooth: CAShapeLayer?
var smoothCorners: Bool = false {
didSet {
updateMaskIfNeeded()
}
}
override func layoutSubviews() {
super.layoutSubviews()
if smoothCorners {
updateMaskIfNeeded()
}
}
func updateMaskIfNeeded() {
if smoothCorners {
if let maskBounds = smooth?.path?.boundingBoxOfPath {
if !bounds.equalTo(maskBounds) || radius != layer.cornerRadius {
updateMaskShape()
}
} else {
let path = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius)
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
smooth = mask
radius = layer.cornerRadius
layer.addObserver(self,
forKeyPath: NSStringFromSelector(#selector(getter: CALayer.cornerRadius)),
options: [],
context: nil)
}
} else if smooth != nil {
layer.mask = nil
smooth = nil
layer.removeObserver(self, forKeyPath: NSStringFromSelector(#selector(getter: CALayer.cornerRadius)))
}
}
func updateMaskShape() {
smooth?.path = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath
radius = layer.cornerRadius
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == NSStringFromSelector(#selector(getter: CALayer.cornerRadius)) {
updateMaskIfNeeded()
}
}
}
@andreytorlopovold
Copy link

I can't understand, what is the difference from cornerRadius?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment