Skip to content

Instantly share code, notes, and snippets.

@vladimir-bebeshko
Forked from morishin/1_playground.swift
Last active December 1, 2018 17:21
Show Gist options
  • Save vladimir-bebeshko/c90742ab1fabbd7d993f51f1ca0acba3 to your computer and use it in GitHub Desktop.
Save vladimir-bebeshko/c90742ab1fabbd7d993f51f1ca0acba3 to your computer and use it in GitHub Desktop.
Custom Shape View with Shadow
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
let container = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 200))
container.backgroundColor = .lightGray
class MyView: UIView {
let shadowView: UIView = {
let view = UIView()
view.backgroundColor = .clear
view.layer.masksToBounds = false
view.layer.shadowOffset = .zero
view.layer.shadowRadius = 5
view.layer.shadowOpacity = 0.5
return view
}()
let shapeView: UIView = {
let view = UIView()
view.layer.masksToBounds = false
view.layer.mask = CAShapeLayer()
return view
}()
var shapeMask: CAShapeLayer {
return shapeView.layer.mask as! CAShapeLayer
}
override var backgroundColor: UIColor? {
get {
return shapeView.backgroundColor
}
set {
shapeView.backgroundColor = newValue
}
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
self.layer.masksToBounds = false
self.backgroundColor = .clear
self.addSubview(shadowView)
self.addSubview(shapeView)
}
override func layoutSubviews() {
super.layoutSubviews()
let shapePath = path(for: self.bounds)
shadowView.frame = self.bounds
shapeView.frame = self.bounds
shadowView.layer.shadowPath = shapePath
shapeMask.path = shapePath
}
private func path(for rect: CGRect) -> CGPath {
return UIBezierPath(ovalIn: rect).cgPath // <-- setup your path here
}
}
let frame = container.frame.insetBy(dx: 20, dy: 20)
let myView = MyView(frame: frame)
myView.backgroundColor = .white
container.addSubview(myView)
PlaygroundPage.current.liveView = container
myView.frame = container.frame.insetBy(dx: 50, dy: 50) //to check that layoutSubviews() works
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' executeOnSourceChanges='false'>
<timeline fileName='timeline.xctimeline'/>
</playground>
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment