Commit 9276f472 by Daniel Dahan

extracting core animations from MaterialView to MaterialLayer

parent f98360e5
...@@ -345,8 +345,6 @@ public class ImageCardView : MaterialPulseView { ...@@ -345,8 +345,6 @@ public class ImageCardView : MaterialPulseView {
borderWidth = MaterialTheme.imageCardView.borderWidth borderWidth = MaterialTheme.imageCardView.borderWidth
borderColor = MaterialTheme.imageCardView.bordercolor borderColor = MaterialTheme.imageCardView.bordercolor
dividerColor = MaterialTheme.imageCardView.dividerColor dividerColor = MaterialTheme.imageCardView.dividerColor
visualLayer.masksToBounds = true
} }
/** /**
...@@ -493,7 +491,7 @@ public class ImageCardView : MaterialPulseView { ...@@ -493,7 +491,7 @@ public class ImageCardView : MaterialPulseView {
internal func prepareImageLayer() { internal func prepareImageLayer() {
imageLayer = CAShapeLayer() imageLayer = CAShapeLayer()
imageLayer.zPosition = 0 imageLayer.zPosition = 0
visualLayer.addSublayer(imageLayer) materialLayer.visualLayer.addSublayer(imageLayer)
} }
// //
......
...@@ -21,29 +21,226 @@ import UIKit ...@@ -21,29 +21,226 @@ import UIKit
@objc(MaterialLayer) @objc(MaterialLayer)
public class MaterialLayer : CAShapeLayer { public class MaterialLayer : CAShapeLayer {
/** /**
:name: visualLayer
*/
public private(set) lazy var visualLayer: CAShapeLayer = CAShapeLayer()
/**
:name: animationDelegate :name: animationDelegate
*/ */
public var animationDelegate: MaterialAnimationDelegate? public var animationDelegate: MaterialAnimationDelegate?
/** /**
:name: x
*/
public var x: CGFloat {
get {
return frame.origin.x
}
set(value) {
frame.origin.x = value
}
}
/**
:name: y
*/
public var y: CGFloat {
get {
return frame.origin.y
}
set(value) {
frame.origin.y = value
}
}
/**
:name: width
*/
public var width: CGFloat {
get {
return frame.size.width
}
set(value) {
frame.size.width = value
if .None != shape {
frame.size.height = value
}
}
}
/**
:name: height
*/
public var height: CGFloat {
get {
return frame.size.height
}
set(value) {
frame.size.height = value
if .None != shape {
frame.size.width = value
}
}
}
/**
:name: image
*/
public var image: UIImage? {
get {
return nil == visualLayer.contents ? nil : UIImage(CGImage: visualLayer.contents as! CGImageRef)
}
set(value) {
visualLayer.contents = value?.CGImage
}
}
/**
:name: contentsRect
*/
public override var contentsRect: CGRect {
get {
return visualLayer.contentsRect
}
set(value) {
visualLayer.contentsRect = contentsRect
}
}
/**
:name: contentsCenter
*/
public override var contentsCenter: CGRect {
get {
return visualLayer.contentsCenter
}
set(value) {
visualLayer.contentsCenter = contentsCenter
}
}
/**
:name: contentsScale
*/
public override var contentsScale: CGFloat {
get {
return visualLayer.contentsScale
}
set(value) {
visualLayer.contentsScale = contentsScale
}
}
/**
:name: contentsGravity
*/
public override var contentsGravity: String {
get {
return visualLayer.contentsGravity
}
set(value) {
visualLayer.contentsGravity = value
}
}
/**
:name: masksToBounds
*/
public override var masksToBounds: Bool {
get {
return visualLayer.masksToBounds
}
set(value) {
visualLayer.masksToBounds = value
}
}
/**
:name: cornerRadius
*/
public override var cornerRadius: CGFloat {
get {
return visualLayer.cornerRadius
}
set(value) {
visualLayer.cornerRadius = value
if .Circle == shape {
shape = .None
}
}
}
/**
:name: shape
*/
public var shape: MaterialShape {
didSet {
if .None != shape {
if width < height {
width = height
} else {
height = width
}
}
}
}
/**
:name: shadowDepth
*/
public var shadowDepth: MaterialDepth {
didSet {
let value: MaterialDepthType = MaterialDepthToValue(shadowDepth)
shadowOffset = value.offset
shadowOpacity = value.opacity
shadowRadius = value.radius
}
}
/**
:name: init :name: init
*/ */
public required init?(coder aDecoder: NSCoder) { public required init?(coder aDecoder: NSCoder) {
shape = .None
shadowDepth = .None
super.init(coder: aDecoder) super.init(coder: aDecoder)
prepareLayer()
} }
/** /**
:name: init :name: init
*/ */
public override init(layer: AnyObject) { public override init(layer: AnyObject) {
shape = .None
shadowDepth = .None
super.init(layer: layer) super.init(layer: layer)
prepareLayer()
} }
/** /**
:name: init :name: init
*/ */
public override init() { public override init() {
shape = .None
shadowDepth = .None
super.init() super.init()
prepareLayer()
}
/**
:name: init
*/
public convenience init(frame: CGRect) {
self.init()
self.frame = frame
}
public override func layoutSublayers() {
super.layoutSublayers()
visualLayer.frame = bounds
visualLayer.position = CGPointMake(width / 2, height / 2)
prepareShape()
} }
/** /**
...@@ -52,14 +249,14 @@ public class MaterialLayer : CAShapeLayer { ...@@ -52,14 +249,14 @@ public class MaterialLayer : CAShapeLayer {
public func animation(animation: CAAnimation) { public func animation(animation: CAAnimation) {
animation.delegate = self animation.delegate = self
if let a: CABasicAnimation = animation as? CABasicAnimation { if let a: CABasicAnimation = animation as? CABasicAnimation {
a.fromValue = (nil == presentationLayer() ? self : presentationLayer() as! CALayer).valueForKeyPath(a.keyPath!) a.fromValue = (nil == visualLayer.presentationLayer() ? self : visualLayer.presentationLayer() as! CALayer).valueForKeyPath(a.keyPath!)
} }
if let a: CAPropertyAnimation = animation as? CAPropertyAnimation { if let a: CAPropertyAnimation = animation as? CAPropertyAnimation {
addAnimation(a, forKey: a.keyPath!) visualLayer.addAnimation(a, forKey: a.keyPath!)
} else if let a: CAAnimationGroup = animation as? CAAnimationGroup { } else if let a: CAAnimationGroup = animation as? CAAnimationGroup {
addAnimation(a, forKey: nil) visualLayer.addAnimation(a, forKey: nil)
} else if let a: CATransition = animation as? CATransition { } else if let a: CATransition = animation as? CATransition {
addAnimation(a, forKey: kCATransition) visualLayer.addAnimation(a, forKey: kCATransition)
} }
} }
...@@ -77,16 +274,35 @@ public class MaterialLayer : CAShapeLayer { ...@@ -77,16 +274,35 @@ public class MaterialLayer : CAShapeLayer {
if let a: CAPropertyAnimation = anim as? CAPropertyAnimation { if let a: CAPropertyAnimation = anim as? CAPropertyAnimation {
if let b: CABasicAnimation = a as? CABasicAnimation { if let b: CABasicAnimation = a as? CABasicAnimation {
MaterialAnimation.animationDisabled({ MaterialAnimation.animationDisabled({
self.setValue(nil == b.toValue ? b.byValue : b.toValue, forKey: b.keyPath!) self.visualLayer.setValue(nil == b.toValue ? b.byValue : b.toValue, forKey: b.keyPath!)
}) })
} }
animationDelegate?.materialAnimationDidStop?(anim, finished: flag) animationDelegate?.materialAnimationDidStop?(anim, finished: flag)
removeAnimationForKey(a.keyPath!) visualLayer.removeAnimationForKey(a.keyPath!)
} else if let a: CAAnimationGroup = anim as? CAAnimationGroup { } else if let a: CAAnimationGroup = anim as? CAAnimationGroup {
for x in a.animations! { for x in a.animations! {
animationDidStop(x, finished: true) animationDidStop(x, finished: true)
} }
} }
} }
/**
:name: prepareLayer
*/
public func prepareLayer() {
// visualLayer
masksToBounds = true
visualLayer.zPosition = -1
addSublayer(visualLayer)
}
//
// :name: prepareShape
//
internal func prepareShape() {
if .Circle == shape {
cornerRadius = width / 2
}
}
} }
...@@ -131,13 +131,6 @@ public class MaterialPulseView : MaterialView { ...@@ -131,13 +131,6 @@ public class MaterialPulseView : MaterialView {
} }
/** /**
:name: actionForLayer
*/
public override func actionForLayer(layer: CALayer, forKey event: String) -> CAAction? {
return nil // returning nil enables the animations for the layer property that are normally disabled.
}
/**
:name: prepareView :name: prepareView
*/ */
public override func prepareView() { public override func prepareView() {
...@@ -161,7 +154,7 @@ public class MaterialPulseView : MaterialView { ...@@ -161,7 +154,7 @@ public class MaterialPulseView : MaterialView {
// pulseLayer // pulseLayer
pulseLayer.hidden = true pulseLayer.hidden = true
pulseLayer.zPosition = 1 pulseLayer.zPosition = 1
visualLayer.addSublayer(pulseLayer) materialLayer.visualLayer.addSublayer(pulseLayer)
} }
// //
......
...@@ -35,11 +35,6 @@ public class MaterialView : UIView { ...@@ -35,11 +35,6 @@ public class MaterialView : UIView {
} }
/** /**
:name: visualLayer
*/
public private(set) lazy var visualLayer: CAShapeLayer = CAShapeLayer()
/**
:name: delegate :name: delegate
*/ */
public weak var delegate: MaterialAnimationDelegate? { public weak var delegate: MaterialAnimationDelegate? {
...@@ -55,8 +50,11 @@ public class MaterialView : UIView { ...@@ -55,8 +50,11 @@ public class MaterialView : UIView {
:name: image :name: image
*/ */
public var image: UIImage? { public var image: UIImage? {
didSet { get {
visualLayer.contents = image?.CGImage return materialLayer.image
}
set(value) {
materialLayer.image = value
} }
} }
...@@ -64,8 +62,11 @@ public class MaterialView : UIView { ...@@ -64,8 +62,11 @@ public class MaterialView : UIView {
:name: contentsRect :name: contentsRect
*/ */
public var contentsRect: CGRect { public var contentsRect: CGRect {
didSet { get {
visualLayer.contentsRect = contentsRect return materialLayer.contentsRect
}
set(value) {
materialLayer.contentsRect = value
} }
} }
...@@ -73,8 +74,11 @@ public class MaterialView : UIView { ...@@ -73,8 +74,11 @@ public class MaterialView : UIView {
:name: contentsCenter :name: contentsCenter
*/ */
public var contentsCenter: CGRect { public var contentsCenter: CGRect {
didSet { get {
visualLayer.contentsCenter = contentsCenter return materialLayer.contentsCenter
}
set(value) {
materialLayer.contentsCenter = value
} }
} }
...@@ -82,8 +86,11 @@ public class MaterialView : UIView { ...@@ -82,8 +86,11 @@ public class MaterialView : UIView {
:name: contentsScale :name: contentsScale
*/ */
public var contentsScale: CGFloat { public var contentsScale: CGFloat {
didSet { get {
visualLayer.contentsScale = contentsScale return materialLayer.contentsScale
}
set(value) {
materialLayer.contentsScale = value
} }
} }
...@@ -92,7 +99,7 @@ public class MaterialView : UIView { ...@@ -92,7 +99,7 @@ public class MaterialView : UIView {
*/ */
public var contentsGravity: MaterialGravity { public var contentsGravity: MaterialGravity {
didSet { didSet {
visualLayer.contentsGravity = MaterialGravityToString(contentsGravity) materialLayer.contentsGravity = MaterialGravityToString(contentsGravity)
} }
} }
...@@ -101,10 +108,10 @@ public class MaterialView : UIView { ...@@ -101,10 +108,10 @@ public class MaterialView : UIView {
*/ */
public var masksToBounds: Bool { public var masksToBounds: Bool {
get { get {
return visualLayer.masksToBounds return materialLayer.masksToBounds
} }
set(value) { set(value) {
visualLayer.masksToBounds = value materialLayer.masksToBounds = value
} }
} }
...@@ -113,7 +120,7 @@ public class MaterialView : UIView { ...@@ -113,7 +120,7 @@ public class MaterialView : UIView {
*/ */
public override var backgroundColor: UIColor? { public override var backgroundColor: UIColor? {
didSet { didSet {
layer.backgroundColor = backgroundColor?.CGColor materialLayer.backgroundColor = backgroundColor?.CGColor
} }
} }
...@@ -122,10 +129,10 @@ public class MaterialView : UIView { ...@@ -122,10 +129,10 @@ public class MaterialView : UIView {
*/ */
public var x: CGFloat { public var x: CGFloat {
get { get {
return frame.origin.x return materialLayer.x
} }
set(value) { set(value) {
frame.origin.x = value materialLayer.x = value
} }
} }
...@@ -134,10 +141,10 @@ public class MaterialView : UIView { ...@@ -134,10 +141,10 @@ public class MaterialView : UIView {
*/ */
public var y: CGFloat { public var y: CGFloat {
get { get {
return frame.origin.y return materialLayer.y
} }
set(value) { set(value) {
frame.origin.y = value materialLayer.y = value
} }
} }
...@@ -146,13 +153,10 @@ public class MaterialView : UIView { ...@@ -146,13 +153,10 @@ public class MaterialView : UIView {
*/ */
public var width: CGFloat { public var width: CGFloat {
get { get {
return frame.size.width return materialLayer.width
} }
set(value) { set(value) {
frame.size.width = value materialLayer.width = value
if .None != shape {
frame.size.height = value
}
} }
} }
...@@ -161,13 +165,10 @@ public class MaterialView : UIView { ...@@ -161,13 +165,10 @@ public class MaterialView : UIView {
*/ */
public var height: CGFloat { public var height: CGFloat {
get { get {
return frame.size.height return materialLayer.height
} }
set(value) { set(value) {
frame.size.height = value materialLayer.height = value
if .None != shape {
frame.size.width = value
}
} }
} }
...@@ -209,24 +210,19 @@ public class MaterialView : UIView { ...@@ -209,24 +210,19 @@ public class MaterialView : UIView {
*/ */
public var shadowRadius: CGFloat { public var shadowRadius: CGFloat {
get { get {
return layer.shadowRadius return materialLayer.shadowRadius
} }
set(value) { set(value) {
layer.shadowRadius = value materialLayer.shadowRadius = value
} }
} }
/** /**
:name: cornerRadius :name: cornerRadius
*/ */
public var cornerRadius: MaterialRadius? { public var cornerRadius: MaterialRadius {
didSet { didSet {
if let v: MaterialRadius = cornerRadius { materialLayer.cornerRadius = MaterialRadiusToValue(cornerRadius)
layer.cornerRadius = MaterialRadiusToValue(v)
if .Circle == shape {
shape = .None
}
}
} }
} }
...@@ -237,9 +233,9 @@ public class MaterialView : UIView { ...@@ -237,9 +233,9 @@ public class MaterialView : UIView {
didSet { didSet {
if .None != shape { if .None != shape {
if width < height { if width < height {
frame.size.width = height width = height
} else { } else {
frame.size.height = width height = width
} }
} }
} }
...@@ -250,7 +246,7 @@ public class MaterialView : UIView { ...@@ -250,7 +246,7 @@ public class MaterialView : UIView {
*/ */
public var borderWidth: MaterialBorder { public var borderWidth: MaterialBorder {
didSet { didSet {
layer.borderWidth = MaterialBorderToValue(borderWidth) materialLayer.borderWidth = MaterialBorderToValue(borderWidth)
} }
} }
...@@ -259,7 +255,7 @@ public class MaterialView : UIView { ...@@ -259,7 +255,7 @@ public class MaterialView : UIView {
*/ */
public var borderColor: UIColor? { public var borderColor: UIColor? {
didSet { didSet {
layer.borderColor = borderColor?.CGColor materialLayer.borderColor = borderColor?.CGColor
} }
} }
...@@ -303,13 +299,11 @@ public class MaterialView : UIView { ...@@ -303,13 +299,11 @@ public class MaterialView : UIView {
:name: init :name: init
*/ */
public required init?(coder aDecoder: NSCoder) { public required init?(coder aDecoder: NSCoder) {
contentsRect = MaterialTheme.view.contentsRect
contentsCenter = MaterialTheme.view.contentsCenter
contentsScale = MaterialTheme.view.contentsScale
contentsGravity = MaterialTheme.view.contentsGravity contentsGravity = MaterialTheme.view.contentsGravity
cornerRadius = .None
shape = .None
borderWidth = MaterialTheme.view.borderWidth borderWidth = MaterialTheme.view.borderWidth
shadowDepth = .None shadowDepth = .None
shape = .None
super.init(coder: aDecoder) super.init(coder: aDecoder)
} }
...@@ -317,18 +311,26 @@ public class MaterialView : UIView { ...@@ -317,18 +311,26 @@ public class MaterialView : UIView {
:name: init :name: init
*/ */
public override init(frame: CGRect) { public override init(frame: CGRect) {
contentsRect = MaterialTheme.view.contentsRect
contentsCenter = MaterialTheme.view.contentsCenter
contentsScale = MaterialTheme.view.contentsScale
contentsGravity = MaterialTheme.view.contentsGravity contentsGravity = MaterialTheme.view.contentsGravity
cornerRadius = .None
shape = .None
borderWidth = MaterialTheme.view.borderWidth borderWidth = MaterialTheme.view.borderWidth
shadowDepth = .None shadowDepth = .None
shape = .None
super.init(frame: frame) super.init(frame: frame)
prepareView() prepareView()
} }
/** /**
:name: layoutSublayersOfLayer
*/
public override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
if self.layer == layer {
prepareShape()
}
}
/**
:name: init :name: init
*/ */
public convenience init() { public convenience init() {
...@@ -336,15 +338,10 @@ public class MaterialView : UIView { ...@@ -336,15 +338,10 @@ public class MaterialView : UIView {
} }
/** /**
:name: layoutSubviews :name: actionForLayer
*/ */
public override func layoutSubviews() { public override func actionForLayer(layer: CALayer, forKey event: String) -> CAAction? {
super.layoutSubviews() return nil // returning nil enables the animations for the layer property that are normally disabled.
prepareShape()
visualLayer.frame = bounds
visualLayer.position = CGPointMake(width / 2, height / 2)
visualLayer.cornerRadius = layer.cornerRadius
} }
/** /**
...@@ -361,16 +358,16 @@ public class MaterialView : UIView { ...@@ -361,16 +358,16 @@ public class MaterialView : UIView {
userInteractionEnabled = MaterialTheme.view.userInteractionEnabled userInteractionEnabled = MaterialTheme.view.userInteractionEnabled
backgroundColor = MaterialTheme.view.backgroundColor backgroundColor = MaterialTheme.view.backgroundColor
shadowDepth = MaterialTheme.view.shadowDepth contentsRect = MaterialTheme.view.contentsRect
contentsCenter = MaterialTheme.view.contentsCenter
contentsScale = MaterialTheme.view.contentsScale
shape = .None
shadowColor = MaterialTheme.view.shadowColor shadowColor = MaterialTheme.view.shadowColor
zPosition = MaterialTheme.view.zPosition zPosition = MaterialTheme.view.zPosition
masksToBounds = MaterialTheme.view.masksToBounds masksToBounds = MaterialTheme.view.masksToBounds
cornerRadius = MaterialTheme.view.cornerRadius cornerRadius = MaterialTheme.view.cornerRadius
borderColor = MaterialTheme.view.bordercolor borderColor = MaterialTheme.view.bordercolor
// visualLayer
visualLayer.zPosition = -1
layer.addSublayer(visualLayer)
} }
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment