Skip to content

Instantly share code, notes, and snippets.

@scalbatty
Created April 9, 2018 09:11
Show Gist options
  • Save scalbatty/7effdc84d976df82cd3215860b7d6122 to your computer and use it in GitHub Desktop.
Save scalbatty/7effdc84d976df82cd3215860b7d6122 to your computer and use it in GitHub Desktop.
A playground for experimenting with the "panel curve" we use at Zenly
// A playground for experimenting with the "panel curve" we use at Zenly
import UIKit
import PlaygroundSupport
// This view displays a filled "panel" curve within the given frame
final class CurvedView: UIView {
// This is the fill color for the shape
private var _color: UIColor = .white
var color: UIColor {
get {
return _color
}
set(newValue) {
_color = newValue
shapeLayer.fillColor = newValue.cgColor
}
}
/* We store the size when computing the shape in order
not to recompute on every call to `layoutSubview` if
it's not necessary.
*/
private var lastComputedSize: CGSize = .zero
override func layoutSubviews() {
super.layoutSubviews()
if bounds.size != lastComputedSize {
computeShape()
}
}
/* The view has a sublayer which is a shape layer,
it's used to draw the curved shape
*/
private let shapeLayer: CAShapeLayer = CAShapeLayer()
private func computeShape() {
// Remove the existing shape layer if necessary
if let sublayer = layer.sublayers?.first {
sublayer.removeFromSuperlayer()
}
// Define the points for the bezier path curve,
// each point has coordinates + 1 or 2 control points
let initialPoint = CGPoint(x: 0, y: frame.size.height * 0.38)
let curve1dest = CGPoint(x: frame.size.width * 0.05, y: frame.size.height * 0.11)
let curve1ControlPoint1 = CGPoint(x: 0.0, y: frame.size.height * 0.13)
let curve1ControlPoint2 = CGPoint(x: frame.size.width * 0.02, y: frame.size.height * 0.13)
let curve2dest = CGPoint(x: frame.size.width / 2.0, y: 0)
let curve2ControlPoint2 = CGPoint(x: frame.size.width * 0.2, y: 0)
let curve3dest = CGPoint(x: frame.size.width * 0.95, y: frame.size.height * 0.11)
let curve3ControlPoint1 = CGPoint(x: frame.size.width * 0.78, y: 0)
let curve4dest = CGPoint(x: frame.size.width, y: frame.size.height * 0.38)
let curve4ControlPoint1 = CGPoint(x: frame.size.width * 0.98, y: frame.size.height * 0.13)
let curve4ControlPoint2 = CGPoint(x: frame.size.width, y: frame.size.height * 0.13)
// Create the actual bezier path
let path: UIBezierPath = UIBezierPath()
path.move(to: initialPoint)
path.addCurve(to: curve1dest, controlPoint1: curve1ControlPoint1, controlPoint2: curve1ControlPoint2)
path.addCurve(to: curve2dest, controlPoint1: curve1dest, controlPoint2: curve2ControlPoint2)
path.addCurve(to: curve3dest, controlPoint1: curve3ControlPoint1, controlPoint2: curve3dest)
path.addCurve(to: curve4dest, controlPoint1: curve4ControlPoint1, controlPoint2: curve4ControlPoint2)
path.addLine(to: CGPoint(x: frame.size.width, y: frame.size.height))
path.addLine(to: CGPoint(x: 0, y: frame.size.height))
path.close()
// Set the path as the path for the shape layer
shapeLayer.path = path.cgPath
shapeLayer.fillColor = _color.cgColor
// Configure the shadow as well
shapeLayer.shadowColor = UIColor(white: 0.0, alpha: 0.3).cgColor
shapeLayer.shadowOffset = CGSize(width: 0, height: 2)
shapeLayer.shadowOpacity = 1
shapeLayer.shadowRadius = 10
shapeLayer.shadowPath = path.cgPath
// Sets the view background clear
layer.backgroundColor = UIColor.clear.cgColor
layer.insertSublayer(shapeLayer, at: 0)
}
}
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let lightBlue = UIColor(red: 0.3, green: 0.7, blue: 1.0, alpha: 1)
let curvedView = CurvedView(frame: CGRect(x: 0, y: 300, width: 375, height: 80))
curvedView.color = lightBlue
// The "curved view" is only the top part of the panel,
// so we add a "main view" underneath.
let mainView = UIView(frame: CGRect(x: 0, y: 380, width: 375, height: 288))
mainView.backgroundColor = lightBlue
view.addSubview(curvedView)
view.addSubview(mainView)
self.view = view
}
}
PlaygroundPage.current.liveView = MyViewController()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment