Commit e132b607 by Daniel Dahan

initial commit for upcoming components

parent dc21d01f
...@@ -66,6 +66,9 @@ ...@@ -66,6 +66,9 @@
9693BF8F1BCB35910087054A /* MaterialTransitionAnimation.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 9693BF8F1BCB35910087054A /* MaterialTransitionAnimation.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9693BF961BCCCB520087054A /* BasicCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9693BF951BCCCB520087054A /* BasicCardView.swift */; settings = {ASSET_TAGS = (); }; }; 9693BF961BCCCB520087054A /* BasicCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9693BF951BCCCB520087054A /* BasicCardView.swift */; settings = {ASSET_TAGS = (); }; };
9693BF971BCCCCB30087054A /* BasicCardView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9693BF951BCCCB520087054A /* BasicCardView.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 9693BF971BCCCCB30087054A /* BasicCardView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9693BF951BCCCB520087054A /* BasicCardView.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9693BF991BCDC1450087054A /* SideNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9693BF981BCDC1450087054A /* SideNavigationViewController.swift */; settings = {ASSET_TAGS = (); }; };
9693BF9C1BCDC16C0087054A /* MaterialCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9693BF9B1BCDC16C0087054A /* MaterialCollectionViewCell.swift */; settings = {ASSET_TAGS = (); }; };
9693BF9E1BCDC1840087054A /* BasicCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9693BF9D1BCDC1840087054A /* BasicCollectionViewCell.swift */; settings = {ASSET_TAGS = (); }; };
9699879C1BC5FE49006D678E /* MaterialTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9699879B1BC5FE49006D678E /* MaterialTextLayer.swift */; settings = {ASSET_TAGS = (); }; }; 9699879C1BC5FE49006D678E /* MaterialTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9699879B1BC5FE49006D678E /* MaterialTextLayer.swift */; settings = {ASSET_TAGS = (); }; };
96C4FABE1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */; settings = {ASSET_TAGS = (); }; }; 96C4FABE1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */; settings = {ASSET_TAGS = (); }; };
96D26BFD1BC23649006478BD /* ImageCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D26BFC1BC23649006478BD /* ImageCardView.swift */; settings = {ASSET_TAGS = (); }; }; 96D26BFD1BC23649006478BD /* ImageCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D26BFC1BC23649006478BD /* ImageCardView.swift */; settings = {ASSET_TAGS = (); }; };
...@@ -120,6 +123,9 @@ ...@@ -120,6 +123,9 @@
964B17B51BBA4BEA002A9CA0 /* MaterialStatusBarStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialStatusBarStyle.swift; sourceTree = "<group>"; }; 964B17B51BBA4BEA002A9CA0 /* MaterialStatusBarStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialStatusBarStyle.swift; sourceTree = "<group>"; };
9693BF851BCB0E0A0087054A /* Material+UIFont.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Material+UIFont.swift"; sourceTree = "<group>"; }; 9693BF851BCB0E0A0087054A /* Material+UIFont.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Material+UIFont.swift"; sourceTree = "<group>"; };
9693BF951BCCCB520087054A /* BasicCardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCardView.swift; sourceTree = "<group>"; }; 9693BF951BCCCB520087054A /* BasicCardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCardView.swift; sourceTree = "<group>"; };
9693BF981BCDC1450087054A /* SideNavigationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideNavigationViewController.swift; sourceTree = "<group>"; };
9693BF9B1BCDC16C0087054A /* MaterialCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialCollectionViewCell.swift; sourceTree = "<group>"; };
9693BF9D1BCDC1840087054A /* BasicCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCollectionViewCell.swift; sourceTree = "<group>"; };
9699879B1BC5FE49006D678E /* MaterialTextLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialTextLayer.swift; sourceTree = "<group>"; }; 9699879B1BC5FE49006D678E /* MaterialTextLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialTextLayer.swift; sourceTree = "<group>"; };
96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialTransitionAnimation.swift; sourceTree = "<group>"; }; 96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialTransitionAnimation.swift; sourceTree = "<group>"; };
96D26BFC1BC23649006478BD /* ImageCardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCardView.swift; sourceTree = "<group>"; }; 96D26BFC1BC23649006478BD /* ImageCardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCardView.swift; sourceTree = "<group>"; };
...@@ -240,6 +246,7 @@ ...@@ -240,6 +246,7 @@
65BDD1551BB6FC60006F7F2B /* Button */, 65BDD1551BB6FC60006F7F2B /* Button */,
65BDD1701BB8CD56006F7F2B /* Label */, 65BDD1701BB8CD56006F7F2B /* Label */,
964B17D71BBB38E2002A9CA0 /* Card */, 964B17D71BBB38E2002A9CA0 /* Card */,
9693BF9A1BCDC15C0087054A /* Collection */,
65BDD1751BB8D44B006F7F2B /* Animation */, 65BDD1751BB8D44B006F7F2B /* Animation */,
964B17B21BBA445D002A9CA0 /* Layout */, 964B17B21BBA445D002A9CA0 /* Layout */,
); );
...@@ -292,6 +299,7 @@ ...@@ -292,6 +299,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
962F3E521BACA68C0004B8AD /* NavigationBarView.swift */, 962F3E521BACA68C0004B8AD /* NavigationBarView.swift */,
9693BF981BCDC1450087054A /* SideNavigationViewController.swift */,
); );
name = Navigation; name = Navigation;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -304,6 +312,15 @@ ...@@ -304,6 +312,15 @@
name = Extensions; name = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9693BF9A1BCDC15C0087054A /* Collection */ = {
isa = PBXGroup;
children = (
9693BF9B1BCDC16C0087054A /* MaterialCollectionViewCell.swift */,
9693BF9D1BCDC1840087054A /* BasicCollectionViewCell.swift */,
);
name = Collection;
sourceTree = "<group>";
};
96B57D4C1B90AF6A00DE7BBB /* Theme */ = { 96B57D4C1B90AF6A00DE7BBB /* Theme */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -473,16 +490,19 @@ ...@@ -473,16 +490,19 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
65BDD15D1BB70D60006F7F2B /* MaterialInsets.swift in Sources */, 65BDD15D1BB70D60006F7F2B /* MaterialInsets.swift in Sources */,
9693BF9E1BCDC1840087054A /* BasicCollectionViewCell.swift in Sources */,
65BDD1471BB5B916006F7F2B /* MaterialView.swift in Sources */, 65BDD1471BB5B916006F7F2B /* MaterialView.swift in Sources */,
65BDD16C1BB88D1A006F7F2B /* MaterialShape.swift in Sources */, 65BDD16C1BB88D1A006F7F2B /* MaterialShape.swift in Sources */,
65AD15EA1BC05B3A0068AF9C /* MaterialLayer.swift in Sources */, 65AD15EA1BC05B3A0068AF9C /* MaterialLayer.swift in Sources */,
65BDD1521BB6EE7C006F7F2B /* RobotoFont.swift in Sources */, 65BDD1521BB6EE7C006F7F2B /* RobotoFont.swift in Sources */,
9693BF991BCDC1450087054A /* SideNavigationViewController.swift in Sources */,
9693BF961BCCCB520087054A /* BasicCardView.swift in Sources */, 9693BF961BCCCB520087054A /* BasicCardView.swift in Sources */,
96D26BFD1BC23649006478BD /* ImageCardView.swift in Sources */, 96D26BFD1BC23649006478BD /* ImageCardView.swift in Sources */,
65BDD1591BB6FE3E006F7F2B /* FlatButton.swift in Sources */, 65BDD1591BB6FE3E006F7F2B /* FlatButton.swift in Sources */,
65BDD1791BB99C0F006F7F2B /* RaisedButton.swift in Sources */, 65BDD1791BB99C0F006F7F2B /* RaisedButton.swift in Sources */,
964B17B41BBA447F002A9CA0 /* MaterialLayout.swift in Sources */, 964B17B41BBA447F002A9CA0 /* MaterialLayout.swift in Sources */,
962F3E531BACA68C0004B8AD /* NavigationBarView.swift in Sources */, 962F3E531BACA68C0004B8AD /* NavigationBarView.swift in Sources */,
9693BF9C1BCDC16C0087054A /* MaterialCollectionViewCell.swift in Sources */,
65BDD14F1BB5EE4A006F7F2B /* MaterialGravity.swift in Sources */, 65BDD14F1BB5EE4A006F7F2B /* MaterialGravity.swift in Sources */,
65BDD1541BB6F473006F7F2B /* MaterialDepth.swift in Sources */, 65BDD1541BB6F473006F7F2B /* MaterialDepth.swift in Sources */,
65BDD1571BB6FC82006F7F2B /* MaterialButton.swift in Sources */, 65BDD1571BB6FC82006F7F2B /* MaterialButton.swift in Sources */,
......
//
// Copyright (C) 2015 GraphKit, Inc. <http://graphkit.io> and other GraphKit contributors.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program located at the root of the software package
// in a file called LICENSE. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
public class BasicCollectionViewCell : MaterialCollectionViewCell {
/**
:name: titleLayer
*/
public private(set) lazy var titleLayer: MaterialTextLayer = MaterialTextLayer()
/**
:name: detailLayer
*/
public private(set) lazy var detailLayer: MaterialTextLayer = MaterialTextLayer()
/**
:name: leftLayer
*/
public private(set) lazy var leftLayer: MaterialLayer = MaterialLayer()
/**
:name: rightLayer
*/
public private(set) lazy var rightLayer: MaterialLayer = MaterialLayer()
/**
:name: prepareView
*/
public override func prepareView() {
super.prepareView()
// title
layer.addSublayer(titleLayer)
// detail
layer.addSublayer(detailLayer)
// left
leftLayer.frame = CGRectMake(-width, 0, width, height)
layer.addSublayer(leftLayer)
// right
rightLayer.frame = CGRectMake(width, 0, width, height)
layer.addSublayer(rightLayer)
}
}
\ No newline at end of file
//
// Copyright (C) 2015 GraphKit, Inc. <http://graphkit.io> and other GraphKit contributors.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program located at the root of the software package
// in a file called LICENSE. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
@objc(MaterialCollectionViewCellDelegate)
public protocol MaterialCollectionViewCellDelegate : MaterialDelegate {
optional func materialCollectionViewCellWillPassThresholdForLeftLayer(cell: MaterialCollectionViewCell)
optional func materialCollectionViewCellWillPassThresholdForRightLayer(cell: MaterialCollectionViewCell)
optional func materialCollectionViewCellDidRevealLeftLayer(cell: MaterialCollectionViewCell)
optional func materialCollectionViewCellDidRevealRightLayer(cell: MaterialCollectionViewCell)
optional func materialCollectionViewCellDidCloseLeftLayer(cell: MaterialCollectionViewCell)
optional func materialCollectionViewCellDidCloseRightLayer(cell: MaterialCollectionViewCell)
}
@objc(MaterialCollectionViewCell)
public class MaterialCollectionViewCell : UICollectionViewCell, UIGestureRecognizerDelegate {
//
// :name: panRecognizer
//
private var panRecognizer: UIPanGestureRecognizer!
//
// :name: leftOnDragRelease
//
private var leftOnDragRelease: Bool = false
//
// :name: rightOnDragRelease
//
private var rightOnDragRelease: Bool = false
//
// :name: originalPosition
//
private var originalPosition: CGPoint!
/**
:name: visualLayer
*/
public private(set) lazy var visualLayer: CAShapeLayer = CAShapeLayer()
/**
:name: pulseLayer
*/
public private(set) lazy var pulseLayer: CAShapeLayer = CAShapeLayer()
/**
:name: revealed
*/
public private(set) lazy var revealed: Bool = false
/**
:name: delegate
*/
public weak var delegate: MaterialCollectionViewCellDelegate?
/**
:name: pulseScale
*/
public lazy var pulseScale: Bool = true
/**
:name: pulseColorOpacity
*/
public var pulseColorOpacity: CGFloat = MaterialTheme.pulseView.pulseColorOpacity {
didSet {
preparePulseLayer()
}
}
/**
:name: pulseColor
*/
public var pulseColor: UIColor? {
didSet {
preparePulseLayer()
}
}
/**
:name: backgroundColor
*/
public override var backgroundColor: UIColor? {
didSet {
layer.backgroundColor = backgroundColor?.CGColor
}
}
/**
: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: shadowColor
*/
public var shadowColor: UIColor? {
didSet {
layer.shadowColor = shadowColor?.CGColor
}
}
/**
:name: shadowOffset
*/
public var shadowOffset: CGSize {
get {
return layer.shadowOffset
}
set(value) {
layer.shadowOffset = value
}
}
/**
:name: shadowOpacity
*/
public var shadowOpacity: Float {
get {
return layer.shadowOpacity
}
set(value) {
layer.shadowOpacity = value
}
}
/**
:name: shadowRadius
*/
public var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set(value) {
layer.shadowRadius = value
}
}
/**
:name: masksToBounds
*/
public var masksToBounds: Bool {
get {
return visualLayer.masksToBounds
}
set(value) {
visualLayer.masksToBounds = value
}
}
/**
:name: cornerRadius
*/
public var cornerRadius: MaterialRadius? {
didSet {
if let v: MaterialRadius = cornerRadius {
layer.cornerRadius = MaterialRadiusToValue(v)
if .Circle == shape {
shape = .None
}
}
}
}
/**
:name: shape
*/
public var shape: MaterialShape {
didSet {
if .None != shape {
if width < height {
frame.size.width = height
} else {
frame.size.height = width
}
}
}
}
/**
:name: borderWidth
*/
public var borderWidth: MaterialBorder {
didSet {
layer.borderWidth = MaterialBorderToValue(borderWidth)
}
}
/**
:name: borderColor
*/
public var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.CGColor
}
}
/**
:name: shadowDepth
*/
public var shadowDepth: MaterialDepth {
didSet {
let value: MaterialDepthType = MaterialDepthToValue(shadowDepth)
shadowOffset = value.offset
shadowOpacity = value.opacity
shadowRadius = value.radius
}
}
/**
:name: position
*/
public var position: CGPoint {
get {
return layer.position
}
set(value) {
layer.position = value
}
}
/**
:name: zPosition
*/
public var zPosition: CGFloat {
get {
return layer.zPosition
}
set(value) {
layer.zPosition = value
}
}
/**
:name: init
*/
public required init?(coder aDecoder: NSCoder) {
borderWidth = .None
shadowDepth = .None
shape = .None
super.init(coder: aDecoder)
}
/**
:name: init
*/
public override init(frame: CGRect) {
borderWidth = .None
shadowDepth = .None
shape = .None
super.init(frame: frame)
prepareView()
}
/**
:name: init
*/
public convenience init() {
self.init(frame: CGRectNull)
}
/**
:name: layoutSubviews
*/
public override func layoutSubviews() {
super.layoutSubviews()
prepareShape()
visualLayer.frame = bounds
visualLayer.position = CGPointMake(width / 2, height / 2)
visualLayer.cornerRadius = layer.cornerRadius
}
/**
:name: animation
*/
public func animation(animation: CAAnimation) {
animation.delegate = self
if let a: CABasicAnimation = animation as? CABasicAnimation {
a.fromValue = (nil == layer.presentationLayer() ? layer : layer.presentationLayer() as! CALayer).valueForKeyPath(a.keyPath!)
}
if let a: CAPropertyAnimation = animation as? CAPropertyAnimation {
layer.addAnimation(a, forKey: a.keyPath!)
} else if let a: CAAnimationGroup = animation as? CAAnimationGroup {
layer.addAnimation(a, forKey: nil)
} else if let a: CATransition = animation as? CATransition {
layer.addAnimation(a, forKey: kCATransition)
}
}
/**
:name: animationDidStart
*/
public override func animationDidStart(anim: CAAnimation) {
(delegate as? MaterialAnimationDelegate)?.materialAnimationDidStart?(anim)
}
/**
:name: animationDidStop
*/
public override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
if let a: CAPropertyAnimation = anim as? CAPropertyAnimation {
if let b: CABasicAnimation = a as? CABasicAnimation {
MaterialAnimation.animationDisabled({
self.layer.setValue(nil == b.toValue ? b.byValue : b.toValue, forKey: b.keyPath!)
})
}
(delegate as? MaterialAnimationDelegate)?.materialAnimationDidStop?(anim, finished: flag)
layer.removeAnimationForKey(a.keyPath!)
} else if let a: CAAnimationGroup = anim as? CAAnimationGroup {
for x in a.animations! {
animationDidStop(x, finished: true)
}
}
}
/**
:name: touchesBegan
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
let point: CGPoint = layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
if true == layer.containsPoint(point) {
let w: CGFloat = width
let h: CGFloat = height
let r: CGFloat = 1.05
let t: CFTimeInterval = 0.25
if nil != pulseColor && 0 < pulseColorOpacity {
MaterialAnimation.animationDisabled({
self.pulseLayer.bounds = CGRectMake(0, 0, 2 * w, 2 * h)
})
MaterialAnimation.animationWithDuration(t, animations: {
self.pulseLayer.hidden = false
})
}
if pulseScale {
layer.addAnimation(MaterialAnimation.scale(r, duration: t), forKey: nil)
}
}
}
/**
:name: touchesMoved
*/
public override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesMoved(touches, withEvent: event)
}
/**
:name: touchesEnded
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
shrink()
}
/**
:name: touchesCancelled
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
shrink()
}
//
// :name: gestureRecognizerShouldBegin
//
public override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
let translation = panGestureRecognizer.translationInView(superview!)
return fabs(translation.x) > fabs(translation.y)
}
return false
}
/**
:name: prepareView
*/
public func prepareView() {
userInteractionEnabled = MaterialTheme.flatButton.userInteractionEnabled
backgroundColor = MaterialTheme.flatButton.backgroundColor
pulseColorOpacity = MaterialTheme.flatButton.pulseColorOpacity
pulseColor = MaterialTheme.flatButton.pulseColor
shadowDepth = MaterialTheme.flatButton.shadowDepth
shadowColor = MaterialTheme.flatButton.shadowColor
zPosition = MaterialTheme.flatButton.zPosition
cornerRadius = MaterialTheme.flatButton.cornerRadius
borderWidth = MaterialTheme.flatButton.borderWidth
borderColor = MaterialTheme.flatButton.bordercolor
shape = MaterialTheme.flatButton.shape
// visualLayer
visualLayer.zPosition = -1
layer.addSublayer(visualLayer)
// pulseLayer
pulseLayer.hidden = true
pulseLayer.zPosition = 1
visualLayer.addSublayer(pulseLayer)
// gesture
panRecognizer = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
panRecognizer.delegate = self
addGestureRecognizer(panRecognizer)
}
//
// :name: handlePanGesture
//
internal func handlePanGesture(recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .Began:
originalPosition = position
rightOnDragRelease = x < -width / 2
leftOnDragRelease = x > width / 2
case .Changed:
let translation = recognizer.translationInView(self)
MaterialAnimation.animationDisabled({
self.position.x = self.originalPosition.x + translation.x
})
rightOnDragRelease = x < -width / 2
leftOnDragRelease = x > width / 2
if !revealed && (leftOnDragRelease || rightOnDragRelease) {
revealed = true
if leftOnDragRelease {
delegate?.materialCollectionViewCellWillPassThresholdForLeftLayer?(self)
} else if rightOnDragRelease {
delegate?.materialCollectionViewCellWillPassThresholdForRightLayer?(self)
}
}
if leftOnDragRelease {
delegate?.materialCollectionViewCellDidRevealLeftLayer?(self)
} else if rightOnDragRelease {
delegate?.materialCollectionViewCellDidRevealRightLayer?(self)
}
case .Ended:
revealed = false
// snap back
let a: CABasicAnimation = MaterialAnimation.position(CGPointMake(width / 2, y + height / 2), duration: 0.25)
a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation(a)
if leftOnDragRelease {
delegate?.materialCollectionViewCellDidCloseLeftLayer?(self)
} else if rightOnDragRelease {
delegate?.materialCollectionViewCellDidCloseRightLayer?(self)
}
default:break
}
}
//
// :name: prepareShape
//
internal func prepareShape() {
if .Circle == shape {
layer.cornerRadius = width / 2
}
}
//
// :name: preparePulseLayer
//
internal func preparePulseLayer() {
pulseLayer.backgroundColor = pulseColor?.colorWithAlphaComponent(pulseColorOpacity).CGColor
}
//
// :name: shrink
//
internal func shrink() {
let t: CFTimeInterval = 0.25
if nil != pulseColor && 0 < pulseColorOpacity {
MaterialAnimation.animationWithDuration(t, animations: {
self.pulseLayer.hidden = true
})
}
if pulseScale {
layer.addAnimation(MaterialAnimation.scale(1, duration: t), forKey: nil)
}
}
}
\ No newline at end of file
//
// Copyright (C) 2015 GraphKit, Inc. <http://graphkit.io> and other GraphKit contributors.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program located at the root of the software package
// in a file called LICENSE. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
public extension UIViewController {
/**
:name: sideNavigationViewController
*/
public var sideNavigationViewController: SideNavigationViewController? {
var viewController: UIViewController? = self
while nil != viewController {
if viewController is SideNavigationViewController {
return viewController as? SideNavigationViewController
}
viewController = viewController?.parentViewController
}
return nil
}
}
@objc(SideNavigationViewController)
public class SideNavigationViewController: UIViewController, UIGestureRecognizerDelegate {
/**
:name: default options
*/
public struct defaultOptions {
public static var bezelWidth: CGFloat = 48
public static var bezelHeight: CGFloat = 48
public static var containerWidth: CGFloat = 240
public static var containerHeight: CGFloat = 240
public static var defaultAnimationDuration: CGFloat = 0.25
public static var threshold: CGFloat = 48
public static var panningEnabled: Bool = true
}
/**
:name: options
*/
public struct options {
public static var shadowOpacity: Float = 0
public static var shadowRadius: CGFloat = 0
public static var shadowOffset: CGSize = CGSizeZero
public static var backdropScale: CGFloat = 1
public static var backdropOpacity: CGFloat = 0.5
public static var hideStatusBar: Bool = true
public static var horizontalThreshold: CGFloat = defaultOptions.threshold
public static var verticalThreshold: CGFloat = defaultOptions.threshold
public static var backdropBackgroundColor: UIColor = MaterialColor.black
public static var animationDuration: CGFloat = defaultOptions.defaultAnimationDuration
public static var leftBezelWidth: CGFloat = defaultOptions.bezelWidth
public static var leftViewContainerWidth: CGFloat = defaultOptions.containerWidth
public static var leftPanFromBezel: Bool = defaultOptions.panningEnabled
}
/**
:name: isViewBasedAppearance
*/
public var isViewBasedAppearance: Bool {
return 0 == NSBundle.mainBundle().objectForInfoDictionaryKey("UIViewControllerBasedStatusBarAppearance") as? Int
}
/**
:name: isLeftContainerOpened
*/
public var isLeftContainerOpened: Bool {
if let c = leftViewContainer {
return c.frame.origin.x != leftOriginX
}
return false
}
/**
:name: isUserInteractionEnabled
*/
public var isUserInteractionEnabled: Bool {
get {
return mainViewContainer!.userInteractionEnabled
}
set(value) {
mainViewContainer?.userInteractionEnabled = value
}
}
//
// :name: originalPosition
//
private var originalPosition: CGPoint!
/**
:name: backdropLayer
*/
public private(set) lazy var backdropLayer: MaterialLayer = MaterialLayer()
/**
:name: mainViewContainer
*/
public private(set) var mainViewContainer: MaterialView?
/**
:name: leftViewContainer
*/
public private(set) var leftViewContainer: MaterialView?
/**
:name: mainViewController
*/
public var mainViewController: UIViewController?
/**
:name: leftViewController
*/
public var leftViewController: UIViewController?
/**
:name: leftAnimation
*/
private var leftAnimation: CAAnimation?
/**
:name: leftPanGesture
*/
public var leftPanGesture: UIPanGestureRecognizer?
/**
:name: leftTapGesture
*/
public var leftTapGesture: UITapGestureRecognizer?
//
// :name: leftOriginX
//
private var leftOriginX: CGFloat {
return -options.leftViewContainerWidth
}
/**
:name: init
*/
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
/**
:name: init
*/
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
/**
:name: init
*/
public convenience init(mainViewController: UIViewController) {
self.init()
self.mainViewController = mainViewController
prepareView()
}
/**
:name: init
*/
public convenience init(mainViewController: UIViewController, leftViewController: UIViewController) {
self.init()
self.mainViewController = mainViewController
self.leftViewController = leftViewController
prepareView()
prepareLeftView()
}
//
// :name: viewDidLoad
//
public override func viewDidLoad() {
super.viewDidLoad()
edgesForExtendedLayout = .None
}
//
// :name: viewWillLayoutSubviews
//
public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if nil != mainViewController {
prepareContainedViewController(&mainViewContainer, viewController: &mainViewController)
}
if nil != leftViewController {
// prepareContainedViewController(&leftViewContainer, viewController: &leftViewController)
}
}
/**
:name: toggleLeftViewContainer
*/
public func toggleLeftViewContainer(velocity: CGFloat = 0) {
openLeftViewContainer(velocity)
}
/**
:name: openLeftViewContainer
*/
public func openLeftViewContainer(velocity: CGFloat = 0) {
if let vc = leftViewContainer {
let w: CGFloat = vc.width
let h: CGFloat = vc.height
let d: Double = Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(vc.frame.origin.x / velocity))))
vc.shadowDepth = .None
MaterialAnimation.animationWithDuration(d, animations: {
vc.position = CGPointMake(w / 2, h / 2)
self.backdropLayer.opacity = Float(options.backdropOpacity)
}) {
self.isUserInteractionEnabled = false
// vc.shadowDepth = .Depth2
}
// print(vc.frame)
// let a: CABasicAnimation = MaterialAnimation.position(CGPointMake(w / 2, h / 2), duration: d)
// a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
// vc.animation(a)
//
////
// UIView.animateWithDuration(d,
// delay: 0,
// options: .CurveEaseInOut,
// animations: { _ in
// vc.frame.origin.x = 0
// self.backdropViewContainer?.layer.opacity = Float(options.backdropOpacity)
// self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.backdropScale, options.backdropScale)
// }
// ) { _ in
// self.isUserInteractionEnabled = false
// }
// c.state = .Opened
// delegate?.sideNavDidOpenLeftViewContainer?(self, container: c)
}
}
//
// :name: gestureRecognizer
//
public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if gestureRecognizer == leftPanGesture {
return gesturePanLeftViewController(gestureRecognizer, withTouchPoint: touch.locationInView(view))
}
if gestureRecognizer == leftTapGesture {
return isLeftContainerOpened && !isPointContainedWithinViewController(&leftViewContainer, point: touch.locationInView(view))
}
return true
}
//
// :name: prepareView
//
internal func prepareView() {
prepareMainContainer()
prepareBackdropContainer()
}
//
// :name: prepareLeftView
//
internal func prepareLeftView() {
prepareContainer(&leftViewContainer, originX: leftOriginX, originY: 0, width: options.leftViewContainerWidth, height: view.bounds.size.height)
prepareLeftGestures()
}
//
// :name: addGestures
//
private func addGestures(inout pan: UIPanGestureRecognizer?, panSelector: Selector, inout tap: UITapGestureRecognizer?, tapSelector: Selector) {
if nil == pan {
pan = UIPanGestureRecognizer(target: self, action: panSelector)
pan!.delegate = self
view.addGestureRecognizer(pan!)
}
if nil == tap {
tap = UITapGestureRecognizer(target: self, action: tapSelector)
tap!.delegate = self
view.addGestureRecognizer(tap!)
}
}
//
// :name: removeGestures
//
private func removeGestures(inout pan: UIPanGestureRecognizer?, inout tap: UITapGestureRecognizer?) {
if let g = pan {
view.removeGestureRecognizer(g)
pan = nil
}
if let g = tap {
view.removeGestureRecognizer(g)
tap = nil
}
}
//
// :name: handleLeftPanGesture
//
internal func handleLeftPanGesture(recognizer: UIPanGestureRecognizer) {
if let vc = leftViewContainer {
switch recognizer.state {
case .Began:
originalPosition = vc.position
toggleStatusBar(true)
case .Changed:
let translation: CGPoint = recognizer.translationInView(vc)
let w: CGFloat = leftViewContainer!.width
MaterialAnimation.animationDisabled({
vc.position.x = self.originalPosition.x + translation.x > (w / 2) ? (w / 2) : self.originalPosition.x + translation.x
self.backdropLayer.opacity = Float(vc.position.x / (w / 2)) / 2
})
case .Ended:
self.isUserInteractionEnabled = false
// snap back
let a: CABasicAnimation = MaterialAnimation.position(CGPointMake(vc.width / 2, vc.height / 2), duration: 0.25)
a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
vc.animation(a)
break
default:break
}
}
}
//
// :name: handleLeftTapGesture
//
internal func handleLeftTapGesture(gesture: UIPanGestureRecognizer) {
}
//
// :name: toggleStatusBar
//
private func toggleStatusBar(hide: Bool = false) {
if options.hideStatusBar {
if isViewBasedAppearance {
UIApplication.sharedApplication().setStatusBarHidden(hide, withAnimation: .Slide)
} else {
dispatch_async(dispatch_get_main_queue(), {
if let w = UIApplication.sharedApplication().keyWindow {
w.windowLevel = hide ? UIWindowLevelStatusBar + 1 : 0
}
})
}
}
}
//
// :name: removeViewController
//
private func removeViewController(inout viewController: UIViewController?) {
if let vc = viewController {
vc.willMoveToParentViewController(nil)
vc.view.removeFromSuperview()
vc.removeFromParentViewController()
}
}
//
// :name: gesturePanLeftViewController
//
private func gesturePanLeftViewController(gesture: UIGestureRecognizer, withTouchPoint point: CGPoint) -> Bool {
return isLeftContainerOpened || options.leftPanFromBezel && isLeftPointContainedWithinRect(point)
}
//
// :name: isLeftPointContainedWithinRect
//
private func isLeftPointContainedWithinRect(point: CGPoint) -> Bool {
return CGRectContainsPoint(CGRectMake(0, 0, options.leftBezelWidth, view.bounds.size.height), point)
}
//
// :name: isPointContainedWithinViewController
//
private func isPointContainedWithinViewController(inout viewContainer: MaterialView?, point: CGPoint) -> Bool {
if let vc = viewContainer {
return CGRectContainsPoint(vc.frame, point)
}
return false
}
//
// :name: prepareMainContainer
//
private func prepareMainContainer() {
mainViewContainer = MaterialView(frame: view.bounds)
mainViewContainer!.backgroundColor = MaterialColor.clear
mainViewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
view.addSubview(mainViewContainer!)
}
//
// :name: prepareBackdropContainer
//
private func prepareBackdropContainer() {
backdropLayer.frame = view.bounds
backdropLayer.backgroundColor = options.backdropBackgroundColor.CGColor
backdropLayer.opacity = 0
view.layer.addSublayer(backdropLayer)
}
//
// :name: prepareLeftGestures
//
private func prepareLeftGestures() {
removeGestures(&leftPanGesture, tap: &leftTapGesture)
addGestures(&leftPanGesture, panSelector: "handleLeftPanGesture:", tap: &leftTapGesture, tapSelector: "handleLeftTapGesture:")
}
//
// :name: prepareContainer
//
private func prepareContainer(inout viewContainer: MaterialView?, originX: CGFloat, originY: CGFloat, width: CGFloat, height: CGFloat) {
viewContainer = MaterialView(frame: CGRectMake(originX, originY, width, height))
viewContainer!.backgroundColor = MaterialColor.red.base
viewContainer!.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
view.addSubview(viewContainer!)
}
//
// :name: prepareContainedViewController
//
private func prepareContainedViewController(inout viewContainer: MaterialView?, inout viewController: UIViewController?) {
if let vc = viewController {
if let c = viewContainer {
addChildViewController(vc)
vc.view.frame = c.frame
c.addSubview(vc.view)
vc.didMoveToParentViewController(self)
}
}
}
}
\ No newline at end of file
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