Commit 7b65a669 by Daniel Dahan

updated pulse animations to a higher accuracy in the Material Design spec

parent 07d04f3f
......@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
9658F1F91CD6AA4900B902C1 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9658F1F81CD6AA4900B902C1 /* Material.framework */; };
9658F1FA1CD6AA4900B902C1 /* Material.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9658F1F81CD6AA4900B902C1 /* Material.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
965E8E721C14A4950035A270 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965E8E711C14A4950035A270 /* AppDelegate.swift */; };
965E8E741C14A4950035A270 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965E8E731C14A4950035A270 /* ViewController.swift */; };
965E8E791C14A4950035A270 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 965E8E781C14A4950035A270 /* Assets.xcassets */; };
......@@ -20,6 +22,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
9658F1FA1CD6AA4900B902C1 /* Material.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
......@@ -27,6 +30,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9658F1F81CD6AA4900B902C1 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Material.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/Material-bshwisidfobstlbomegqyybbrygh/Build/Products/Debug-iphoneos/Material.framework"; sourceTree = "<absolute>"; };
965E8E6E1C14A4950035A270 /* MaterialButton.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MaterialButton.app; sourceTree = BUILT_PRODUCTS_DIR; };
965E8E711C14A4950035A270 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
965E8E731C14A4950035A270 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
......@@ -40,6 +44,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9658F1F91CD6AA4900B902C1 /* Material.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -49,6 +54,7 @@
965E8E651C14A4950035A270 = {
isa = PBXGroup;
children = (
9658F1F81CD6AA4900B902C1 /* Material.framework */,
965E8E701C14A4950035A270 /* MaterialButton */,
965E8E6F1C14A4950035A270 /* Products */,
);
......
......@@ -45,6 +45,10 @@ class ViewController: UIViewController {
prepareFabButtonExample()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
/// General preparation statements.
private func prepareView() {
view.backgroundColor = MaterialColor.white
......@@ -52,9 +56,12 @@ class ViewController: UIViewController {
/// Prepares the FlatButton.
private func prepareFlatButtonExample() {
let button: FlatButton = FlatButton(frame: CGRectMake(107, 107, 200, 65))
let w: CGFloat = 200
let button: FlatButton = FlatButton(frame: CGRectMake((view.bounds.width - w) / 2, 100, w, 48))
button.setTitle("Flat", forState: .Normal)
button.titleLabel!.font = RobotoFont.mediumWithSize(32)
button.setTitleColor(MaterialColor.blue.base, forState: .Normal)
button.pulseColor = MaterialColor.blue.base
button.titleLabel!.font = RobotoFont.mediumWithSize(24)
// Add button to UIViewController.
view.addSubview(button)
......@@ -62,9 +69,12 @@ class ViewController: UIViewController {
/// Prepares the RaisedButton.
private func prepareRaisedButtonExample() {
let button: RaisedButton = RaisedButton(frame: CGRectMake(107, 207, 200, 65))
let w: CGFloat = 200
let button: RaisedButton = RaisedButton(frame: CGRectMake((view.bounds.width - w) / 2, 200, w, 48))
button.setTitle("Raised", forState: .Normal)
button.titleLabel!.font = RobotoFont.mediumWithSize(32)
button.setTitleColor(MaterialColor.blue.base, forState: .Normal)
button.pulseColor = MaterialColor.blue.base
button.titleLabel!.font = RobotoFont.mediumWithSize(24)
// Add button to UIViewController.
view.addSubview(button)
......@@ -72,8 +82,9 @@ class ViewController: UIViewController {
/// Prepares the FabButton.
private func prepareFabButtonExample() {
let img: UIImage? = UIImage(named: "ic_create_white")
let button: FabButton = FabButton(frame: CGRectMake(175, 315, 64, 64))
let w: CGFloat = 64
let img: UIImage? = MaterialIcon.cm.pen
let button: FabButton = FabButton(frame: CGRectMake((view.bounds.width - w) / 2, 300, w, 64))
button.setImage(img, forState: .Normal)
button.setImage(img, forState: .Highlighted)
......
......@@ -7,8 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
9658F1F01CD3C0EA00B902C1 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9658F1EF1CD3C0EA00B902C1 /* Material.framework */; };
9658F1F11CD3C0EA00B902C1 /* Material.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9658F1EF1CD3C0EA00B902C1 /* Material.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
966F57A11C226BAA009185B7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 966F57A01C226BAA009185B7 /* AppDelegate.swift */; };
966F57A31C226BAA009185B7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 966F57A21C226BAA009185B7 /* ViewController.swift */; };
966F57A81C226BAA009185B7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 966F57A71C226BAA009185B7 /* Assets.xcassets */; };
......@@ -22,7 +20,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
9658F1F11CD3C0EA00B902C1 /* Material.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
......@@ -30,7 +27,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9658F1EF1CD3C0EA00B902C1 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Material.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/Material-bshwisidfobstlbomegqyybbrygh/Build/Products/Debug-iphoneos/Material.framework"; sourceTree = "<absolute>"; };
966F579D1C226BAA009185B7 /* TextField.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TextField.app; sourceTree = BUILT_PRODUCTS_DIR; };
966F57A01C226BAA009185B7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
966F57A21C226BAA009185B7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
......@@ -44,7 +40,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9658F1F01CD3C0EA00B902C1 /* Material.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -54,7 +49,6 @@
966F57941C226BAA009185B7 = {
isa = PBXGroup;
children = (
9658F1EF1CD3C0EA00B902C1 /* Material.framework */,
966F579F1C226BAA009185B7 /* TextField */,
966F579E1C226BAA009185B7 /* Products */,
);
......
......@@ -42,6 +42,8 @@ public class FabButton : MaterialButton {
super.prepareView()
depth = .Depth1
shape = .Circle
backgroundColor = MaterialColor.red.darken1
backgroundColor = MaterialColor.blue.base
pulseColor = MaterialColor.white
tintColor = MaterialColor.white
}
}
\ No newline at end of file
......@@ -42,6 +42,5 @@ public class FlatButton : MaterialButton {
super.prepareView()
cornerRadiusPreset = .Radius1
contentEdgeInsetsPreset = .WideRectangle3
pulseColor = MaterialColor.blue.accent3
}
}
\ No newline at end of file
......@@ -46,24 +46,15 @@ public class MaterialButton : UIButton {
*/
public weak var delegate: MaterialDelegate?
/// To use a single pulse and have it focused when held.
@IBInspectable public var pulseFocus: Bool = false
/// A pulse layer for focus handling.
public private(set) var pulseLayer: CAShapeLayer?
/// Sets whether the scaling animation should be used.
@IBInspectable public lazy var pulseScale: Bool = true
/// An Array of pulse layers.
public private(set) lazy var pulseLayers: Array<CAShapeLayer> = Array<CAShapeLayer>()
/// The opacity value for the pulse animation.
@IBInspectable public var pulseOpacity: CGFloat = 0.25
@IBInspectable public var pulseOpacity: CGFloat = 0.12
/// The color of the pulse effect.
@IBInspectable public var pulseColor: UIColor?
/// Sets a pulse animation to always radiate from the center
@IBInspectable public var pulseCenter: Bool = false
/**
This property is the same as clipsToBounds. It crops any of the view's
contents from bleeding past the view's frame. If an image is set using
......@@ -412,20 +403,12 @@ public class MaterialButton : UIButton {
*/
public func pulse(point: CGPoint? = nil) {
let p: CGPoint = nil == point ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : point!
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if let v: UIColor = pulseColor {
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: p, width: width, height: height, duration: duration)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
MaterialAnimation.delay(duration) { [weak self] in
if let l: CALayer = self?.layer {
if let w: CGFloat = self?.width {
MaterialAnimation.shrinkAnimation(l, width: w, duration: duration)
}
if let color: UIColor = pulseColor {
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: p, width: width, height: height, pulseLayers: &pulseLayers)
}
MaterialAnimation.delay(0.35) { [weak self] in
if let s: MaterialButton = self {
MaterialAnimation.pulseContractAnimation(s.layer, pulseColor: s.pulseColor, pulseLayers: &s.pulseLayers)
}
}
}
......@@ -438,20 +421,7 @@ public class MaterialButton : UIButton {
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if pulseFocus {
pulseLayer = CAShapeLayer()
}
if let v: UIColor = pulseColor {
let point: CGPoint = pulseCenter ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: point, width: width, height: height, duration: duration, pulseLayer: pulseLayer)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
}
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer), width: width, height: height, pulseLayers: &pulseLayers)
}
/**
......@@ -462,7 +432,7 @@ public class MaterialButton : UIButton {
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -473,7 +443,7 @@ public class MaterialButton : UIButton {
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -484,8 +454,9 @@ public class MaterialButton : UIButton {
when subclassing.
*/
public func prepareView() {
pulseColor = MaterialColor.black
contentScaleFactor = MaterialDevice.scale
prepareVisualLayer()
pulseColor = MaterialColor.white
}
/// Prepares the visualLayer property.
......
......@@ -46,14 +46,8 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
*/
public weak var delegate: MaterialDelegate?
/// To use a single pulse and have it focused when held.
@IBInspectable public var pulseFocus: Bool = false
/// A pulse layer for focus handling.
public private(set) var pulseLayer: CAShapeLayer?
/// Sets whether the scaling animation should be used.
@IBInspectable public lazy var pulseScale: Bool = true
/// An Array of pulse layers.
public private(set) lazy var pulseLayers: Array<CAShapeLayer> = Array<CAShapeLayer>()
/// The opcaity value for the pulse animation.
@IBInspectable public var pulseOpacity: CGFloat = 0.25
......@@ -61,9 +55,6 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
/// The color of the pulse effect.
@IBInspectable public var pulseColor: UIColor?
/// Sets a pulse animation to always radiate from the center
@IBInspectable public var pulseCenter: Bool = false
/**
A property that manages an image for the visualLayer's contents
property. Images should not be set to the backing layer's contents
......@@ -517,20 +508,12 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
*/
public func pulse(point: CGPoint? = nil) {
let p: CGPoint = nil == point ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : point!
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if let v: UIColor = pulseColor {
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: p, width: width, height: height, duration: duration)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
MaterialAnimation.delay(duration) { [weak self] in
if let l: CALayer = self?.layer {
if let w: CGFloat = self?.width {
MaterialAnimation.shrinkAnimation(l, width: w, duration: duration)
}
if let color: UIColor = pulseColor {
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: p, width: width, height: height, pulseLayers: &pulseLayers)
}
MaterialAnimation.delay(0.35) { [weak self] in
if let s: MaterialCollectionViewCell = self {
MaterialAnimation.pulseContractAnimation(s.layer, pulseColor: s.pulseColor, pulseLayers: &s.pulseLayers)
}
}
}
......@@ -543,20 +526,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if pulseFocus {
pulseLayer = CAShapeLayer()
}
if let v: UIColor = pulseColor {
let point: CGPoint = pulseCenter ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: point, width: width, height: height, duration: duration, pulseLayer: pulseLayer)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
}
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer), width: width, height: height, pulseLayers: &pulseLayers)
}
/**
......@@ -567,7 +537,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -578,7 +548,7 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -589,9 +559,9 @@ public class MaterialCollectionViewCell : UICollectionViewCell {
when subclassing.
*/
public func prepareView() {
pulseColor = MaterialColor.black
contentScaleFactor = MaterialDevice.scale
prepareVisualLayer()
pulseColor = MaterialColor.grey.lighten1
pulseScale = false
}
/// Prepares the visualLayer property.
......
......@@ -32,100 +32,69 @@ import UIKit
internal extension MaterialAnimation {
/**
Triggers the pulse animation.
Triggers the expanding animation.
- Parameter layer: Container CALayer.
- Parameter visualLayer: A CAShapeLayer for the pulseLayer.
- Parameter color: The UIColor for the pulse.
- Parameter pulseColor: The UIColor for the pulse.
- Parameter point: A point to pulse from.
- Parameter width: Container width.
- Parameter height: Container height.
- Parameter duration: Animation duration.
- Parameter pulseLayer: An Optional pulseLayer to use in the animation.
- Parameter pulseLayers: An Array of CAShapeLayers used in the animation.
*/
internal static func pulseAnimation(layer: CALayer, visualLayer: CALayer, color: UIColor, point: CGPoint, width: CGFloat, height: CGFloat, duration: NSTimeInterval, pulseLayer: CAShapeLayer? = nil) {
let r: CGFloat = (width < height ? height : width) / 2
let f: CGFloat = 3
let v: CGFloat = r / f
let d: CGFloat = 2 * f
var b: Bool = false
var pLayer: CAShapeLayer?
if nil == pulseLayer {
pLayer = CAShapeLayer()
b = true
} else {
pLayer = pulseLayer
}
pLayer!.hidden = true
pLayer!.zPosition = 1
pLayer!.backgroundColor = color.CGColor
visualLayer.addSublayer(pLayer!)
MaterialAnimation.animationDisabled {
pLayer!.bounds = CGRectMake(0, 0, v, v)
pLayer!.position = point
pLayer!.cornerRadius = r / d
pLayer!.hidden = false
}
pLayer!.addAnimation(MaterialAnimation.scale((b ? 3 : 1.7) * d, duration: duration), forKey: nil)
if b {
MaterialAnimation.delay(duration) {
MaterialAnimation.animateWithDuration(duration, animations: {
pLayer?.hidden = true
}) {
pLayer?.removeFromSuperlayer()
}
internal static func pulseExpandAnimation(layer: CALayer, visualLayer: CALayer, pulseColor: UIColor?, pulseOpacity: CGFloat, point: CGPoint, width: CGFloat, height: CGFloat, inout pulseLayers: Array<CAShapeLayer>) {
if let color: UIColor = pulseColor {
if let n: CGFloat = width < height ? height : width {
if let pOpacity: CGFloat = pulseOpacity {
let bLayer: CAShapeLayer = CAShapeLayer()
let pLayer: CAShapeLayer = CAShapeLayer()
bLayer.addSublayer(pLayer)
pulseLayers.insert(bLayer, atIndex: 0)
visualLayer.insertSublayer(bLayer, atIndex: 0)
MaterialAnimation.animationDisabled({
bLayer.frame = visualLayer.bounds
pLayer.bounds = CGRectMake(0, 0, n, n)
pLayer.position = point
pLayer.cornerRadius = n / 2
pLayer.backgroundColor = color.colorWithAlphaComponent(pOpacity).CGColor
pLayer.transform = CATransform3DMakeAffineTransform(CGAffineTransformMakeScale(0, 0))
})
bLayer.setValue(false, forKey: "animated")
bLayer.addAnimation(MaterialAnimation.backgroundColor(color.colorWithAlphaComponent(pOpacity / 2), duration: 0.35), forKey: nil)
pLayer.addAnimation(MaterialAnimation.scale(1, duration: 0.35), forKey: nil)
MaterialAnimation.delay(0.35, completion: {
bLayer.setValue(true, forKey: "animated")
})
}
} else {
MaterialAnimation.delay(duration / 2) {
pLayer?.addAnimation(MaterialAnimation.scale(1.3 * d, duration: duration), forKey: nil)
}
}
}
/**
Triggers the expanding animation.
Triggers the contracting animation.
- Parameter layer: Container CALayer.
- Parameter scale: The scale factor when expanding.
- Parameter duration: Animation duration.
- Parameter pulseColor: The UIColor for the pulse.
- Parameter pulseLayers: An Array of CAShapeLayers used in the animation.
*/
internal static func expandAnimation(layer: CALayer, scale: CGFloat, duration: NSTimeInterval) {
layer.addAnimation(MaterialAnimation.scale(scale, duration: duration), forKey: nil)
}
internal static func pulseContractAnimation(layer: CALayer, pulseColor: UIColor?, inout pulseLayers: Array<CAShapeLayer>) {
if let color: UIColor = pulseColor {
if let bLayer: CAShapeLayer = pulseLayers.popLast() {
let animated: Bool? = bLayer.valueForKey("animated") as? Bool
MaterialAnimation.delay(true == animated ? 0 : 0.10) {
if let pLayer: CAShapeLayer = bLayer.sublayers?.first as? CAShapeLayer {
bLayer.addAnimation(MaterialAnimation.backgroundColor(color.colorWithAlphaComponent(0), duration: 0.35), forKey: nil)
pLayer.addAnimation(MaterialAnimation.animationGroup([
MaterialAnimation.scale(1.35),
MaterialAnimation.backgroundColor(color.colorWithAlphaComponent(0))
], duration: 0.35), forKey: nil)
/**
Triggers the shrinking animation.
- Parameter layer: Container CALayer.
- Parameter width: Container width.
- Parameter duration: Animation duration.
- Parameter pulseLayer: An Optional pulseLayer to use in the animation.
*/
internal static func shrinkAnimation(layer: CALayer, width: CGFloat, duration: NSTimeInterval, pulseLayer: CAShapeLayer? = nil) {
if let v: CAShapeLayer = pulseLayer {
MaterialAnimation.animateWithDuration(duration, animations: {
v.hidden = true
}) {
v.removeFromSuperlayer()
MaterialAnimation.delay(0.35) {
pLayer.removeFromSuperlayer()
bLayer.removeFromSuperlayer()
}
}
}
layer.addAnimation(MaterialAnimation.scale(1, duration: duration), forKey: nil)
}
/**
Retrieves the animation duration time.
- Parameter width: Container width.
- Returns: An NSTimeInterval value that represents the animation time.
*/
internal static func pulseDuration(width: CGFloat) -> NSTimeInterval {
var t: CFTimeInterval = CFTimeInterval(1.5 * width / MaterialDevice.width)
if 0.55 < t || 0.25 > t {
t = 0.55
}
return t / 1.3
}
}
\ No newline at end of file
......@@ -34,11 +34,8 @@ public class MaterialPulseView : MaterialView {
/// To use a single pulse and have it focused when held.
@IBInspectable public var pulseFocus: Bool = false
/// A pulse layer for focus handling.
public private(set) var pulseLayer: CAShapeLayer?
/// Sets whether the scaling animation should be used.
@IBInspectable public lazy var pulseScale: Bool = true
/// An Array of pulse layers.
public private(set) lazy var pulseLayers: Array<CAShapeLayer> = Array<CAShapeLayer>()
/// The opcaity value for the pulse animation.
@IBInspectable public var pulseOpacity: CGFloat = 0.25
......@@ -46,9 +43,6 @@ public class MaterialPulseView : MaterialView {
/// The color of the pulse effect.
@IBInspectable public var pulseColor: UIColor?
/// Sets a pulse animation to always radiate from the center
@IBInspectable public var pulseCenter: Bool = false
/**
Triggers the pulse animation.
- Parameter point: A Optional point to pulse from, otherwise pulses
......@@ -56,20 +50,12 @@ public class MaterialPulseView : MaterialView {
*/
public func pulse(point: CGPoint? = nil) {
let p: CGPoint = nil == point ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : point!
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if let v: UIColor = pulseColor {
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: p, width: width, height: height, duration: duration)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
MaterialAnimation.delay(duration) { [weak self] in
if let l: CALayer = self?.layer {
if let w: CGFloat = self?.width {
MaterialAnimation.shrinkAnimation(l, width: w, duration: duration)
}
if let color: UIColor = pulseColor {
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: p, width: width, height: height, pulseLayers: &pulseLayers)
}
MaterialAnimation.delay(0.35) { [weak self] in
if let s: MaterialPulseView = self {
MaterialAnimation.pulseContractAnimation(s.layer, pulseColor: s.pulseColor, pulseLayers: &s.pulseLayers)
}
}
}
......@@ -82,20 +68,7 @@ public class MaterialPulseView : MaterialView {
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if pulseFocus {
pulseLayer = CAShapeLayer()
}
if let v: UIColor = pulseColor {
let point: CGPoint = pulseCenter ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: point, width: width, height: height, duration: duration, pulseLayer: pulseLayer)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
}
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer), width: width, height: height, pulseLayers: &pulseLayers)
}
/**
......@@ -106,7 +79,7 @@ public class MaterialPulseView : MaterialView {
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -117,7 +90,7 @@ public class MaterialPulseView : MaterialView {
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -129,6 +102,7 @@ public class MaterialPulseView : MaterialView {
*/
public override func prepareView() {
super.prepareView()
pulseColor = MaterialColor.white
pulseColor = MaterialColor.black
contentScaleFactor = MaterialDevice.scale
}
}
......@@ -45,14 +45,8 @@ public class MaterialTableViewCell : UITableViewCell {
*/
public weak var delegate: MaterialDelegate?
/// To use a single pulse and have it focused when held.
@IBInspectable public var pulseFocus: Bool = false
/// A pulse layer for focus handling.
public private(set) var pulseLayer: CAShapeLayer?
/// Sets whether the scaling animation should be used.
@IBInspectable public lazy var pulseScale: Bool = true
/// An Array of pulse layers.
public private(set) lazy var pulseLayers: Array<CAShapeLayer> = Array<CAShapeLayer>()
/// The opcaity value for the pulse animation.
@IBInspectable public var pulseOpacity: CGFloat = 0.25
......@@ -60,9 +54,6 @@ public class MaterialTableViewCell : UITableViewCell {
/// The color of the pulse effect.
@IBInspectable public var pulseColor: UIColor?
/// Sets a pulse animation to always radiate from the center
@IBInspectable public var pulseCenter: Bool = false
/**
This property is the same as clipsToBounds. It crops any of the view's
contents from bleeding past the view's frame. If an image is set using
......@@ -367,20 +358,12 @@ public class MaterialTableViewCell : UITableViewCell {
*/
public func pulse(point: CGPoint? = nil) {
let p: CGPoint = nil == point ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : point!
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if let v: UIColor = pulseColor {
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: p, width: width, height: height, duration: duration)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
MaterialAnimation.delay(duration) { [weak self] in
if let l: CALayer = self?.layer {
if let w: CGFloat = self?.width {
MaterialAnimation.shrinkAnimation(l, width: w, duration: duration)
}
if let color: UIColor = pulseColor {
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: p, width: width, height: height, pulseLayers: &pulseLayers)
}
MaterialAnimation.delay(0.35) { [weak self] in
if let s: MaterialTableViewCell = self {
MaterialAnimation.pulseContractAnimation(s.layer, pulseColor: s.pulseColor, pulseLayers: &s.pulseLayers)
}
}
}
......@@ -393,20 +376,7 @@ public class MaterialTableViewCell : UITableViewCell {
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
let duration: NSTimeInterval = MaterialAnimation.pulseDuration(width)
if pulseFocus {
pulseLayer = CAShapeLayer()
}
if let v: UIColor = pulseColor {
let point: CGPoint = pulseCenter ? CGPointMake(CGFloat(width / 2), CGFloat(height / 2)) : layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
MaterialAnimation.pulseAnimation(layer, visualLayer: visualLayer, color: v.colorWithAlphaComponent(pulseOpacity), point: point, width: width, height: height, duration: duration, pulseLayer: pulseLayer)
}
if pulseScale {
MaterialAnimation.expandAnimation(layer, scale: 1.05, duration: duration)
}
MaterialAnimation.pulseExpandAnimation(layer, visualLayer: visualLayer, pulseColor: pulseColor, pulseOpacity: pulseOpacity, point: layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer), width: width, height: height, pulseLayers: &pulseLayers)
}
/**
......@@ -417,7 +387,7 @@ public class MaterialTableViewCell : UITableViewCell {
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -428,7 +398,7 @@ public class MaterialTableViewCell : UITableViewCell {
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
MaterialAnimation.shrinkAnimation(layer, width: width, duration: MaterialAnimation.pulseDuration(width), pulseLayer: pulseLayer)
MaterialAnimation.pulseContractAnimation(layer, pulseColor: pulseColor, pulseLayers: &pulseLayers)
}
/**
......@@ -441,8 +411,8 @@ public class MaterialTableViewCell : UITableViewCell {
public func prepareView() {
prepareVisualLayer()
selectionStyle = .None
pulseColor = MaterialColor.grey.lighten1
pulseScale = false
pulseColor = MaterialColor.black
contentScaleFactor = MaterialDevice.scale
imageView?.userInteractionEnabled = false
textLabel?.userInteractionEnabled = false
detailTextLabel?.userInteractionEnabled = false
......
......@@ -44,7 +44,6 @@ public class MenuView : MaterialPulseView {
public override func prepareView() {
super.prepareView()
pulseColor = nil
pulseScale = false
clipsToBounds = false
backgroundColor = nil
}
......
......@@ -407,7 +407,6 @@ public class NavigationBar : UINavigationBar {
/// Prepares the backButton.
internal func prepareBackButton() {
backButton.pulseScale = false
backButton.pulseColor = MaterialColor.white
backButton.setImage(backButtonImage, forState: .Normal)
backButton.setImage(backButtonImage, forState: .Highlighted)
......
......@@ -44,6 +44,5 @@ public class RaisedButton : MaterialButton {
cornerRadiusPreset = .Radius1
contentEdgeInsetsPreset = .WideRectangle3
backgroundColor = MaterialColor.white
pulseColor = MaterialColor.blue.accent3
}
}
\ No newline at end of file
......@@ -130,7 +130,6 @@ public class SearchBar : StatusBarView {
clearButton.contentEdgeInsets = UIEdgeInsetsZero
clearButton.pulseColor = MaterialColor.black
clearButton.pulseOpacity = 0.12
clearButton.pulseScale = false
clearButton.tintColor = placeholderTextColor
clearButton.setImage(image, forState: .Normal)
clearButton.setImage(image, forState: .Highlighted)
......
......@@ -153,9 +153,9 @@ public class TextField : UITextField {
}
/// TextField's text property observer.
public override var text: String? {
@IBInspectable public override var text: String? {
didSet {
if (text == nil || text!.isEmpty) && !self.isFirstResponder() {
if (nil == text || text!.isEmpty) && !isFirstResponder() {
placeholderEditingDidEndAnimation()
}
}
......@@ -255,7 +255,6 @@ public class TextField : UITextField {
clearFlatButton = FlatButton(frame: CGRectZero)
clearFlatButton!.contentEdgeInsets = UIEdgeInsetsZero
clearFlatButton!.pulseColor = nil
clearFlatButton!.pulseScale = false
clearFlatButton!.tintColor = placeholderColor
clearFlatButton!.setImage(image, forState: .Normal)
clearFlatButton!.setImage(image, forState: .Highlighted)
......@@ -293,7 +292,6 @@ public class TextField : UITextField {
visibilityFlatButton = FlatButton(frame: CGRectZero)
visibilityFlatButton!.contentEdgeInsets = UIEdgeInsetsZero
visibilityFlatButton!.pulseColor = nil
visibilityFlatButton!.pulseScale = false
visibilityFlatButton!.tintColor = placeholderColor
visibilityFlatButton!.setImage(image, forState: .Normal)
visibilityFlatButton!.setImage(image, forState: .Highlighted)
......@@ -516,7 +514,7 @@ public class TextField : UITextField {
/// Layout the detailLabel.
public func layoutDetailLabel() {
var h: CGFloat = nil == detail ? 12 : detailLabel.font.stringSize(detail!, constrainedToWidth: Double(width)).height
let h: CGFloat = nil == detail ? 12 : detailLabel.font.stringSize(detail!, constrainedToWidth: Double(width)).height
detailLabel.frame = CGRectMake(0, divider.frame.origin.y + 8, width, h)
}
......
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