Commit 62eb6c6d by Daniel Dahan

Merge pull request #14 from GraphKit/development

Development
parents 493444cf 1e46d9c1
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
963832851B89070E0015F710 /* CapturePreview.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9638325F1B88E5BF0015F710 /* CapturePreview.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 963832851B89070E0015F710 /* CapturePreview.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9638325F1B88E5BF0015F710 /* CapturePreview.swift */; settings = {ATTRIBUTES = (Public, ); }; };
963832881B8908180015F710 /* Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 963832871B8908180015F710 /* Layout.swift */; }; 963832881B8908180015F710 /* Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 963832871B8908180015F710 /* Layout.swift */; };
963832891B89097D0015F710 /* Layout.swift in Headers */ = {isa = PBXBuildFile; fileRef = 963832871B8908180015F710 /* Layout.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 963832891B89097D0015F710 /* Layout.swift in Headers */ = {isa = PBXBuildFile; fileRef = 963832871B8908180015F710 /* Layout.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9638329E1B8EC34D0015F710 /* AddFabButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9638329D1B8EC34D0015F710 /* AddFabButton.swift */; };
9A94D0F91B895C8C00F586A5 /* Roboto.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9AAC38531B89559900FE6B2D /* Roboto.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 9A94D0F91B895C8C00F586A5 /* Roboto.swift in Headers */ = {isa = PBXBuildFile; fileRef = 9AAC38531B89559900FE6B2D /* Roboto.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9A94D0FA1B895EA500F586A5 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 963832631B88E5BF0015F710 /* LICENSE */; }; 9A94D0FA1B895EA500F586A5 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 963832631B88E5BF0015F710 /* LICENSE */; };
9A94D0FB1B895EA500F586A5 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9AAC38591B8956E300FE6B2D /* Roboto-Regular.ttf */; }; 9A94D0FB1B895EA500F586A5 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9AAC38591B8956E300FE6B2D /* Roboto-Regular.ttf */; };
...@@ -73,6 +74,7 @@ ...@@ -73,6 +74,7 @@
963832671B88E5BF0015F710 /* TextStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextStorage.swift; sourceTree = "<group>"; }; 963832671B88E5BF0015F710 /* TextStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextStorage.swift; sourceTree = "<group>"; };
963832681B88E5BF0015F710 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; }; 963832681B88E5BF0015F710 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
963832871B8908180015F710 /* Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Layout.swift; sourceTree = "<group>"; }; 963832871B8908180015F710 /* Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Layout.swift; sourceTree = "<group>"; };
9638329D1B8EC34D0015F710 /* AddFabButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFabButton.swift; sourceTree = "<group>"; };
9A94D1081B8A3F5100F586A5 /* MaterialPulseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialPulseView.swift; sourceTree = "<group>"; }; 9A94D1081B8A3F5100F586A5 /* MaterialPulseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialPulseView.swift; sourceTree = "<group>"; };
9A94D10A1B8A485C00F586A5 /* ImageCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCard.swift; sourceTree = "<group>"; }; 9A94D10A1B8A485C00F586A5 /* ImageCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCard.swift; sourceTree = "<group>"; };
9AAC384C1B89528900FE6B2D /* BasicCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCard.swift; sourceTree = "<group>"; }; 9AAC384C1B89528900FE6B2D /* BasicCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCard.swift; sourceTree = "<group>"; };
...@@ -193,6 +195,7 @@ ...@@ -193,6 +195,7 @@
children = ( children = (
65B9657D1B8A7C330055B139 /* MaterialButton.swift */, 65B9657D1B8A7C330055B139 /* MaterialButton.swift */,
963832601B88E5BF0015F710 /* FabButton.swift */, 963832601B88E5BF0015F710 /* FabButton.swift */,
9638329D1B8EC34D0015F710 /* AddFabButton.swift */,
963832611B88E5BF0015F710 /* FlatButton.swift */, 963832611B88E5BF0015F710 /* FlatButton.swift */,
963832651B88E5BF0015F710 /* RaisedButton.swift */, 963832651B88E5BF0015F710 /* RaisedButton.swift */,
); );
...@@ -367,6 +370,7 @@ ...@@ -367,6 +370,7 @@
65B965751B8A60A00055B139 /* MaterialView.swift in Sources */, 65B965751B8A60A00055B139 /* MaterialView.swift in Sources */,
963832711B88E5BF0015F710 /* Text.swift in Sources */, 963832711B88E5BF0015F710 /* Text.swift in Sources */,
9638326A1B88E5BF0015F710 /* CapturePreview.swift in Sources */, 9638326A1B88E5BF0015F710 /* CapturePreview.swift in Sources */,
9638329E1B8EC34D0015F710 /* AddFabButton.swift in Sources */,
65B965721B8A578D0055B139 /* MaterialViewController.swift in Sources */, 65B965721B8A578D0055B139 /* MaterialViewController.swift in Sources */,
9AAC38541B89559900FE6B2D /* Roboto.swift in Sources */, 9AAC38541B89559900FE6B2D /* Roboto.swift in Sources */,
65B9657E1B8A7C330055B139 /* MaterialButton.swift in Sources */, 65B9657E1B8A7C330055B139 /* 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 AddFabButton : FabButton {
private var verticalLine: UIView!
private var horizontalLine: UIView!
//
// :name: prepareButton
//
public override func prepareButton() {
super.prepareButton()
prepareVerticalLine()
prepareHorizontalLine()
}
//
// :name: prepareVerticalLine
//
private func prepareVerticalLine() {
verticalLine = UIView(frame: CGRectMake(0, 0, lineWidth, CGRectGetHeight(backgroundColorView.frame) / 3))
verticalLine.backgroundColor = .whiteColor()
verticalLine.center = backgroundColorView.center
backgroundColorView.addSubview(verticalLine)
}
//
// :name: prepareHorizontalLine
//
private func prepareHorizontalLine() {
horizontalLine = UIView(frame: CGRectMake(0, 0, CGRectGetWidth(backgroundColorView.frame) / 3, lineWidth))
horizontalLine.backgroundColor = .whiteColor()
horizontalLine.center = backgroundColorView.center
backgroundColorView.addSubview(horizontalLine)
}
}
...@@ -19,141 +19,29 @@ ...@@ -19,141 +19,29 @@
import UIKit import UIKit
public class FabButton : MaterialButton { public class FabButton : MaterialButton {
/**
var lineWidth: CGFloat = 2.0 :name: lineWidth
*/
public var lineWidth: CGFloat = 2
public convenience init() { //
self.init(frame: CGRectZero) // :name: prepareButton
} //
internal override func prepareButton() {
public override func drawRect(rect: CGRect) { super.prepareButton()
setupContext(rect) color = .redColor()
setupBackgroundColorView() pulseColor = .whiteColor()
setupPlus() backgroundColorView.layer.cornerRadius = bounds.width / 2
}
public required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
applyShadow()
}
public required override init(frame: CGRect) {
super.init(frame: frame)
initialize()
applyShadow()
}
func initialize() {
color = UIColor.redColor()
pulseColor = UIColor.whiteColor()
setTranslatesAutoresizingMaskIntoConstraints(false)
}
func setupContext(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, rect)
CGContextSetFillColorWithColor(context, UIColor.clearColor().CGColor)
CGContextFillPath(context)
CGContextRestoreGState(context);
}
// We need this view so we can use the masksToBounds
// so the pulse doesn't animate off the button
func setupBackgroundColorView() {
backgroundColorView = UIView()
backgroundColorView!.frame = bounds
backgroundColorView!.layer.cornerRadius = bounds.width / 2.0
backgroundColorView!.backgroundColor = color
backgroundColorView!.layer.masksToBounds = true
backgroundColorView!.userInteractionEnabled = false
insertSubview(backgroundColorView!, atIndex: 0)
}
// I make the + with two views because
// The label is not actually vertically and horizontally aligned
// Quick hack instead of subclassing UILabel and override drawTextInRect
func setupPlus() {
setupVerticalLine()
setupHorizontalLine()
}
func setupVerticalLine() {
verticalLine = UIView(frame: CGRectMake(0, 0, lineWidth, CGRectGetHeight(backgroundColorView!.frame) / 3.0))
verticalLine!.backgroundColor = UIColor.whiteColor()
verticalLine!.center = backgroundColorView!.center
backgroundColorView!.addSubview(verticalLine!)
} }
func setupHorizontalLine() {
horizontalLine = UIView(frame: CGRectMake(0, 0, CGRectGetWidth(backgroundColorView!.frame) / 3.0, lineWidth))
horizontalLine!.backgroundColor = UIColor.whiteColor()
horizontalLine!.center = backgroundColorView!.center
backgroundColorView!.addSubview(horizontalLine!)
}
func applyShadow() {
layer.shadowOffset = CGSizeMake(1, 1)
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOpacity = 0.5
layer.shadowRadius = 5
}
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
pulseTouches(touches)
}
public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesEnded(touches, withEvent: event)
shrink()
removePulse()
}
public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) { //
super.touchesCancelled(touches, withEvent: event) // :name: pulseTouches
shrink() //
removePulse() internal override func pulseTouches(touches: Set<NSObject>) {
super.pulseTouches(touches)
UIView.animateWithDuration(0.3, animations: {
self.pulseView!.transform = CGAffineTransformMakeScale(3, 3)
self.transform = CGAffineTransformMakeScale(1.1, 1.1)
})
} }
func pulseTouches(touches: NSSet) {
let touch = touches.allObjects.last as! UITouch
let touchLocation = touch.locationInView(self)
pulseView = UIView()
pulseView!.frame = CGRectMake(0, 0, bounds.width, bounds.height)
pulseView!.layer.cornerRadius = bounds.width / 2.0
pulseView!.center = touchLocation
pulseView!.backgroundColor = pulseColor!.colorWithAlphaComponent(0.5)
backgroundColorView!.addSubview(pulseView!)
UIView.animateWithDuration(0.3,
animations: {
self.pulseView!.transform = CGAffineTransformMakeScale(3, 3)
self.transform = CGAffineTransformMakeScale(1.1, 1.1)
},
completion: nil
)
}
func shrink() {
UIView.animateWithDuration(0.3,
delay: 0.0,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 10,
options: nil,
animations: {
self.transform = CGAffineTransformIdentity
},
completion: nil
)
}
func removePulse() {
UIView.animateWithDuration(0.3, animations: { _ in
self.pulseView?.alpha = 0.0
}) { (finished) -> Void in
self.pulseView?.removeFromSuperview()
self.pulseView = nil
}
}
} }
...@@ -19,104 +19,30 @@ ...@@ -19,104 +19,30 @@
import UIKit import UIKit
public class FlatButton : MaterialButton { public class FlatButton : MaterialButton {
public var textColor: UIColor? /**
:name: textColor
*/
public var textColor: UIColor?
public override func drawRect(rect: CGRect) { //
setupContext(rect) // :name: prepareButton
setupBackgroundColorView() //
} internal override func prepareButton() {
super.prepareButton()
public required init(coder aDecoder: NSCoder) { pulseColor = .whiteColor()
super.init(coder: aDecoder) backgroundColorView.layer.cornerRadius = 3
initialize() }
applyShadow()
} //
// :name: pulseTouches
public required override init(frame: CGRect) { //
super.init(frame: frame) internal override func pulseTouches(touches: Set<NSObject>) {
initialize() super.pulseTouches(touches)
applyShadow() textColor = titleLabel?.textColor
} UIView.animateWithDuration(0.3, animations: {
self.pulseView!.transform = CGAffineTransformMakeScale(10, 10)
func initialize() { self.transform = CGAffineTransformMakeScale(1.05, 1.1)
backgroundColorView = UIView() self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
pulseColor = UIColor.whiteColor() })
setTranslatesAutoresizingMaskIntoConstraints(false) }
}
func setupContext(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context);
CGContextSetFillColorWithColor(context, UIColor.clearColor().CGColor)
CGContextFillPath(context)
CGContextRestoreGState(context);
}
// We need this view so we can use the masksToBounds
// so the pulse doesn't animate off the button
func setupBackgroundColorView() {
backgroundColorView!.frame = self.bounds
backgroundColorView!.layer.cornerRadius = 3.0
backgroundColorView!.backgroundColor = UIColor.clearColor()
backgroundColorView!.layer.masksToBounds = true
backgroundColorView!.userInteractionEnabled = false
self.insertSubview(backgroundColorView!, atIndex: 0)
}
func applyShadow() {
layer.shadowOffset = CGSizeMake(1, 1)
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOpacity = 0.5
layer.shadowRadius = 5
}
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
pulseTouches(touches)
}
public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesEnded(touches, withEvent: event)
shrink()
removePulse()
}
public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
super.touchesCancelled(touches, withEvent: event)
shrink()
removePulse()
}
func pulseTouches(touches: NSSet) {
let touch = touches.allObjects.last as! UITouch
let touchLocation = touch.locationInView(self)
pulseView = UIView()
pulseView!.frame = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.height)
pulseView!.layer.cornerRadius = bounds.height / 2.0
pulseView!.center = touchLocation
pulseView!.backgroundColor = pulseColor!.colorWithAlphaComponent(0.5)
backgroundColorView!.addSubview(pulseView!)
textColor = self.titleLabel?.textColor
UIView.animateWithDuration(0.3, animations: {
self.pulseView!.transform = CGAffineTransformMakeScale(10, 10)
self.transform = CGAffineTransformMakeScale(1.05, 1.1)
self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
}, completion: nil)
}
func shrink() {
UIView.animateWithDuration(0.3, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 10, options: nil, animations: {
self.transform = CGAffineTransformIdentity
}, completion: nil)
}
func removePulse() {
UIView.animateWithDuration(0.3, animations: { () -> Void in
self.pulseView!.alpha = 0.0
self.setTitleColor(self.textColor, forState: .Normal)
}) { (finished) -> Void in
self.pulseView!.removeFromSuperview()
self.pulseView = nil
}
}
} }
...@@ -19,11 +19,174 @@ ...@@ -19,11 +19,174 @@
import UIKit import UIKit
public class MaterialButton : UIButton { public class MaterialButton : UIButton {
//
// :name: backgroundColorView
//
internal lazy var backgroundColorView: UIView = UIView()
//
// :name: pulseView
//
internal var pulseView: UIView?
/**
:name: color
*/
public var color: UIColor? public var color: UIColor?
/**
:name: pulseColor
*/
public var pulseColor: UIColor? public var pulseColor: UIColor?
internal var pulseView: UIView? /**
internal var verticalLine: UIView? :name: init
internal var horizontalLine: UIView? */
internal var backgroundColorView: UIView? public required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
prepareView()
}
/**
:name: init
*/
public required override init(frame: CGRect) {
super.init(frame: frame)
prepareView()
}
/**
:name: init
*/
public convenience init() {
self.init(frame: CGRectZero)
}
/**
:name: touchesBegan
*/
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
pulseTouches(touches)
}
/**
:name: touchesEnded
*/
public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesEnded(touches, withEvent: event)
shrink()
removePulse()
}
/**
:name: touchesCancelled
*/
public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
super.touchesCancelled(touches, withEvent: event)
shrink()
removePulse()
}
/**
:name: drawRect
*/
final public override func drawRect(rect: CGRect) {
prepareContext(rect)
prepareShadow()
prepareButton()
prepareBackgroundColorView()
}
//
// :name: prepareButton
//
internal func prepareButton() {
backgroundColorView.frame = bounds
}
//
// :name: pulseTouches
//
internal func pulseTouches(touches: Set<NSObject>) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInView(self)
pulseView = UIView()
pulseView!.frame = CGRectMake(0, 0, bounds.width, bounds.height)
pulseView!.layer.cornerRadius = bounds.width / 2
pulseView!.center = touchLocation
pulseView!.backgroundColor = pulseColor?.colorWithAlphaComponent(0.5)
backgroundColorView.addSubview(pulseView!)
}
//
// :name: prepareBackgroundColorView
//
// We need this view so we can use the masksToBounds
// so the pulse doesn't animate off the button
private func prepareBackgroundColorView() {
backgroundColorView.backgroundColor = color
backgroundColorView.layer.masksToBounds = true
backgroundColorView.userInteractionEnabled = false
insertSubview(backgroundColorView, atIndex: 0)
}
//
// :name: prepareView
//
private func prepareView() {
setTranslatesAutoresizingMaskIntoConstraints(false)
}
//
// :name: prepareShadow
//
private func prepareShadow() {
layer.shadowOffset = CGSizeMake(1, 1)
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOpacity = 0.5
layer.shadowRadius = 5
}
//
// :name: prepareContext
//
private func prepareContext(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, rect)
CGContextSetFillColorWithColor(context, UIColor.clearColor().CGColor)
CGContextFillPath(context)
CGContextRestoreGState(context);
}
//
// :name: shrink
//
private func shrink() {
UIView.animateWithDuration(0.3,
delay: 0,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 10,
options: nil,
animations: {
self.transform = CGAffineTransformIdentity
},
completion: nil
)
}
//
// :name: removePulse
//
private func removePulse() {
UIView.animateWithDuration(0.3,
animations: { _ in
self.pulseView?.alpha = 0
}
) { _ in
self.pulseView?.removeFromSuperview()
self.pulseView = nil
}
}
} }
...@@ -19,112 +19,32 @@ ...@@ -19,112 +19,32 @@
import UIKit import UIKit
public class RaisedButton : MaterialButton { public class RaisedButton : MaterialButton {
public override func drawRect(rect: CGRect) { /**
setupContext(rect) :name: textColor
setupBackgroundColorView() */
} public var textColor: UIColor?
public required init(coder aDecoder: NSCoder) { //
super.init(coder: aDecoder) // :name: prepareButton
initialize() //
applyShadow() internal override func prepareButton() {
} super.prepareButton()
color = .redColor()
public required override init(frame: CGRect) { pulseColor = .whiteColor()
super.init(frame: frame) backgroundColorView.layer.cornerRadius = 3
initialize() }
applyShadow()
} //
// :name: pulseTouches
func initialize() { //
color = UIColor.redColor() internal override func pulseTouches(touches: Set<NSObject>) {
backgroundColorView = UIView() super.pulseTouches(touches)
pulseColor = UIColor.whiteColor() textColor = titleLabel?.textColor
setTranslatesAutoresizingMaskIntoConstraints(false) UIView.animateWithDuration(0.3, animations: {
} self.pulseView!.transform = CGAffineTransformMakeScale(10, 10)
self.transform = CGAffineTransformMakeScale(1.05, 1.1)
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
super.touchesBegan(touches, withEvent: event) })
pulseTouches(touches)
}
public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
super.touchesEnded(touches, withEvent: event)
shrink()
removePulse()
}
public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
super.touchesCancelled(touches, withEvent: event)
shrink()
removePulse()
}
private func setupContext(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context);
CGContextSetFillColorWithColor(context, UIColor.clearColor().CGColor)
CGContextFillPath(context)
CGContextRestoreGState(context);
}
// We need this view so we can use the masksToBounds
// so the pulse doesn't animate off the button
private func setupBackgroundColorView() {
backgroundColorView!.frame = self.bounds
backgroundColorView!.layer.cornerRadius = 3.0
backgroundColorView!.backgroundColor = color!
backgroundColorView!.layer.masksToBounds = true
backgroundColorView!.userInteractionEnabled = false
self.insertSubview(backgroundColorView!, atIndex: 0)
}
private func applyShadow() {
layer.shadowOffset = CGSizeMake(1, 1)
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOpacity = 0.5
layer.shadowRadius = 5
}
private func pulseTouches(touches: NSSet) {
let touch = touches.allObjects.last as! UITouch
let touchLocation = touch.locationInView(self)
pulseView = UIView()
pulseView!.frame = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.height)
pulseView!.layer.cornerRadius = bounds.height / 2.0
pulseView!.center = touchLocation
pulseView!.backgroundColor = pulseColor!.colorWithAlphaComponent(0.5)
backgroundColorView!.addSubview(pulseView!)
UIView.animateWithDuration(0.3,
animations: {
self.pulseView!.transform = CGAffineTransformMakeScale(10, 10)
self.transform = CGAffineTransformMakeScale(1.05, 1.1)
},
completion: nil
)
}
private func shrink() {
UIView.animateWithDuration(0.3,
delay: 0.0,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 10,
options: nil,
animations: {
self.transform = CGAffineTransformIdentity
},
completion: nil
)
}
private func removePulse() {
UIView.animateWithDuration(0.3,
animations: { () -> Void in
self.pulseView!.alpha = 0.0
}) { _ in
self.pulseView!.removeFromSuperview()
self.pulseView = nil
}
} }
} }
...@@ -42,20 +42,20 @@ public class SideNavContainer : Printable { ...@@ -42,20 +42,20 @@ public class SideNavContainer : Printable {
@objc(SideNavDelegate) @objc(SideNavDelegate)
public protocol SideNavDelegate { public protocol SideNavDelegate {
// left // left
optional func sideNavDidBeginLeftPan(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidBeginLeftPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidChangeLeftPan(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidChangeLeftPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidEndLeftPan(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidEndLeftPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidOpenLeftViewContainer(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidOpenLeftViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidCloseLeftViewContainer(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidCloseLeftViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidTapLeft(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidTapLeft(nav: SideNavController, container: SideNavContainer)
// right // right
optional func sideNavDidBeginRightPan(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidBeginRightPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidChangeRightPan(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidChangeRightPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidEndRightPan(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidEndRightPan(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidOpenRightViewContainer(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidOpenRightViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidCloseRightViewContainer(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidCloseRightViewContainer(nav: SideNavController, container: SideNavContainer)
optional func sideNavDidTapRight(sideNav: SideNavController, container: SideNavContainer) optional func sideNavDidTapRight(nav: SideNavController, container: SideNavContainer)
} }
@objc(SideNavController) @objc(SideNavController)
...@@ -97,14 +97,17 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -97,14 +97,17 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
:name: isLeftContainerOpened :name: isLeftContainerOpened
*/ */
public var isLeftContainerOpened: Bool { public var isLeftContainerOpened: Bool {
return 0 == leftViewContainer.frame.origin.x return 0 == leftViewContainer?.frame.origin.x
} }
/** /**
:name: isRightContainerOpened :name: isRightContainerOpened
*/ */
public var isRightContainerOpened: Bool { public var isRightContainerOpened: Bool {
return rightViewContainer.frame.origin.x == rightOriginX - rightViewContainer.frame.size.width if let c = rightViewContainer {
return c.frame.origin.x == rightOriginX - c.frame.size.width
}
return false
} }
/** /**
...@@ -112,42 +115,42 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -112,42 +115,42 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
*/ */
public private(set) var isUserInteractionEnabled: Bool { public private(set) var isUserInteractionEnabled: Bool {
get { get {
return mainViewContainer.userInteractionEnabled return mainViewContainer!.userInteractionEnabled
} }
set(value) { set(value) {
mainViewContainer.userInteractionEnabled = value mainViewContainer?.userInteractionEnabled = value
} }
} }
/** /**
:name: backdropViewContainer :name: backdropViewContainer
*/ */
public private(set) var backdropViewContainer: UIView! public private(set) var backdropViewContainer: UIView?
/** /**
:name: mainViewContainer :name: mainViewContainer
*/ */
public private(set) var mainViewContainer: UIView! public private(set) var mainViewContainer: UIView?
/** /**
:name: leftViewContainer :name: leftViewContainer
*/ */
public private(set) var leftViewContainer: UIView! public private(set) var leftViewContainer: UIView?
/** /**
:name: rightViewContainer :name: rightViewContainer
*/ */
public private(set) var rightViewContainer: UIView! public private(set) var rightViewContainer: UIView?
/** /**
:name: leftContainer :name: leftContainer
*/ */
public private(set) var leftContainer: SideNavContainer! public private(set) var leftContainer: SideNavContainer?
/** /**
:name: rightContainer :name: rightContainer
*/ */
public private(set) var rightContainer: SideNavContainer! public private(set) var rightContainer: SideNavContainer?
/** /**
:name: mainViewController :name: mainViewController
...@@ -220,7 +223,8 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -220,7 +223,8 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
self.init() self.init()
self.mainViewController = mainViewController self.mainViewController = mainViewController
self.leftViewController = leftViewController self.leftViewController = leftViewController
setupView() setupView()
setupLeftView()
} }
/** /**
...@@ -230,7 +234,8 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -230,7 +234,8 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
self.init() self.init()
self.mainViewController = mainViewController self.mainViewController = mainViewController
self.rightViewController = rightViewController self.rightViewController = rightViewController
setupView() setupView()
setupRightView()
} }
/** /**
...@@ -242,6 +247,8 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -242,6 +247,8 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
self.leftViewController = leftViewController self.leftViewController = leftViewController
self.rightViewController = rightViewController self.rightViewController = rightViewController
setupView() setupView()
setupLeftView()
setupRightView()
} }
// //
...@@ -257,9 +264,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -257,9 +264,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
public override func viewWillLayoutSubviews() { public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews() super.viewWillLayoutSubviews()
prepareContainedViewController(mainViewContainer, viewController: mainViewController) prepareContainedViewController(&mainViewContainer, viewController: &mainViewController)
prepareContainedViewController(leftViewContainer, viewController: leftViewController) prepareContainedViewController(&leftViewContainer, viewController: &leftViewController)
prepareContainedViewController(rightViewContainer, viewController: rightViewController) prepareContainedViewController(&rightViewContainer, viewController: &rightViewController)
} }
// //
...@@ -267,24 +274,28 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -267,24 +274,28 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
public override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { public override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
mainViewContainer.transform = CGAffineTransformMakeScale(1, 1) mainViewContainer?.transform = CGAffineTransformMakeScale(1, 1)
leftViewContainer.hidden = true leftViewContainer?.hidden = true
rightViewContainer.hidden = true rightViewContainer?.hidden = true
coordinator.animateAlongsideTransition(nil) { _ in coordinator.animateAlongsideTransition(nil) { _ in
self.toggleWindow() self.toggleWindow()
self.backdropViewContainer.layer.opacity = 0 self.backdropViewContainer?.layer.opacity = 0
self.mainViewContainer.transform = CGAffineTransformMakeScale(1, 1) self.mainViewContainer?.transform = CGAffineTransformMakeScale(1, 1)
self.isUserInteractionEnabled = true self.isUserInteractionEnabled = true
self.leftViewContainer.frame.origin.x = self.leftOriginX if let vc = self.leftViewContainer {
self.leftViewContainer.hidden = false vc.frame.origin.x = self.leftOriginX
self.removeShadow(self.leftViewContainer) vc.hidden = false
self.prepareLeftGestures() self.removeShadow(&self.leftViewContainer)
self.prepareLeftGestures()
}
self.rightViewContainer.frame.origin.x = self.rightOriginX if let vc = self.rightViewContainer {
self.rightViewContainer.hidden = false vc.frame.origin.x = self.rightOriginX
self.removeShadow(self.rightViewContainer) vc.hidden = false
self.prepareRightGestures() self.removeShadow(&self.rightViewContainer)
self.prepareRightGestures()
}
} }
} }
...@@ -306,95 +317,111 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -306,95 +317,111 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
:name: openLeftViewContainer :name: openLeftViewContainer
*/ */
public func openLeftViewContainer(velocity: CGFloat = 0) { public func openLeftViewContainer(velocity: CGFloat = 0) {
prepareContainerToOpen(&leftViewController, viewContainer: &leftViewContainer, state: leftContainer.state) if let vc = leftViewContainer {
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(leftViewContainer.frame.origin.x / velocity)))), if let c = leftContainer {
delay: 0, prepareContainerToOpen(&leftViewController, viewContainer: &leftViewContainer, state: c.state)
options: .CurveEaseInOut, UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(vc.frame.origin.x / velocity)))),
animations: { _ in delay: 0,
self.leftViewContainer.frame.origin.x = 0 options: .CurveEaseInOut,
self.backdropViewContainer.layer.opacity = Float(options.contentViewOpacity) animations: { _ in
self.mainViewContainer.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale) vc.frame.origin.x = 0
self.backdropViewContainer?.layer.opacity = Float(options.contentViewOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale)
}
) { _ in
self.isUserInteractionEnabled = false
self.leftViewController?.endAppearanceTransition()
}
c.state = .Opened
delegate?.sideNavDidOpenLeftViewContainer?(self, container: c)
} }
) { _ in
self.isUserInteractionEnabled = false
self.leftViewController?.endAppearanceTransition()
} }
leftContainer.state = .Opened
delegate?.sideNavDidOpenLeftViewContainer?(self, container: leftContainer)
} }
/** /**
:name: openRightViewContainer :name: openRightViewContainer
*/ */
public func openRightViewContainer(velocity: CGFloat = 0) { public func openRightViewContainer(velocity: CGFloat = 0) {
prepareContainerToOpen(&rightViewController, viewContainer: &rightViewContainer, state: rightContainer.state) if let vc = rightViewContainer {
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(fabs(rightViewContainer.frame.origin.x - rightOriginX) / velocity)))), if let c = rightContainer {
delay: 0, prepareContainerToOpen(&rightViewController, viewContainer: &rightViewContainer, state: c.state)
options: .CurveEaseInOut, UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, Double(fabs(vc.frame.origin.x - rightOriginX) / velocity)))),
animations: { _ in delay: 0,
self.rightViewContainer.frame.origin.x = self.rightOriginX - self.rightViewContainer.frame.size.width options: .CurveEaseInOut,
self.backdropViewContainer.layer.opacity = Float(options.contentViewOpacity) animations: { _ in
self.mainViewContainer.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale) vc.frame.origin.x = self.rightOriginX - vc.frame.size.width
self.backdropViewContainer?.layer.opacity = Float(options.contentViewOpacity)
self.mainViewContainer?.transform = CGAffineTransformMakeScale(options.contentViewScale, options.contentViewScale)
}
) { _ in
self.isUserInteractionEnabled = false
self.rightViewController?.endAppearanceTransition()
}
c.state = .Opened
delegate?.sideNavDidOpenRightViewContainer?(self, container: c)
} }
) { _ in
self.isUserInteractionEnabled = false
self.rightViewController?.endAppearanceTransition()
} }
rightContainer.state = .Opened
delegate?.sideNavDidOpenRightViewContainer?(self, container: rightContainer)
} }
/** /**
:name: closeLeftViewContainer :name: closeLeftViewContainer
*/ */
public func closeLeftViewContainer(velocity: CGFloat = 0) { public func closeLeftViewContainer(velocity: CGFloat = 0) {
prepareContainerToClose(&leftViewController, state: leftContainer.state) if let vc = leftViewContainer {
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, fabs(leftViewContainer.frame.origin.x - leftOriginX) / velocity))), if let c = leftContainer {
delay: 0, prepareContainerToClose(&leftViewController, state: c.state)
options: .CurveEaseInOut, UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, fabs(vc.frame.origin.x - leftOriginX) / velocity))),
animations: { _ in delay: 0,
self.leftViewContainer.frame.origin.x = self.leftOriginX options: .CurveEaseInOut,
self.backdropViewContainer.layer.opacity = 0 animations: { _ in
self.mainViewContainer.transform = CGAffineTransformMakeScale(1, 1) vc.frame.origin.x = self.leftOriginX
self.backdropViewContainer?.layer.opacity = 0
self.mainViewContainer?.transform = CGAffineTransformMakeScale(1, 1)
}
) { _ in
self.removeShadow(&self.leftViewContainer)
self.isUserInteractionEnabled = true
self.leftViewController?.endAppearanceTransition()
}
c.state = .Closed
delegate?.sideNavDidCloseLeftViewContainer?(self, container: c)
} }
) { _ in
self.removeShadow(self.leftViewContainer)
self.isUserInteractionEnabled = true
self.leftViewController?.endAppearanceTransition()
} }
leftContainer.state = .Closed
delegate?.sideNavDidCloseLeftViewContainer?(self, container: leftContainer)
} }
/** /**
:name: closeRightViewContainer :name: closeRightViewContainer
*/ */
public func closeRightViewContainer(velocity: CGFloat = 0) { public func closeRightViewContainer(velocity: CGFloat = 0) {
prepareContainerToClose(&rightViewController, state: rightContainer.state) if let vc = rightViewContainer {
UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, fabs(rightViewContainer.frame.origin.x - rightOriginX) / velocity))), if let c = rightContainer {
delay: 0, prepareContainerToClose(&rightViewController, state: c.state)
options: .CurveEaseInOut, UIView.animateWithDuration(Double(0 == velocity ? options.animationDuration : fmax(0.1, fmin(1, fabs(vc.frame.origin.x - rightOriginX) / velocity))),
animations: { _ in delay: 0,
self.rightViewContainer.frame.origin.x = self.rightOriginX options: .CurveEaseInOut,
self.backdropViewContainer.layer.opacity = 0 animations: { _ in
self.mainViewContainer.transform = CGAffineTransformMakeScale(1, 1) vc.frame.origin.x = self.rightOriginX
self.backdropViewContainer?.layer.opacity = 0
self.mainViewContainer?.transform = CGAffineTransformMakeScale(1, 1)
}
) { _ in
self.removeShadow(&self.rightViewContainer)
self.isUserInteractionEnabled = true
self.rightViewController?.endAppearanceTransition()
}
c.state = .Closed
delegate?.sideNavDidCloseRightViewContainer?(self, container: c)
} }
) { _ in
self.removeShadow(self.rightViewContainer)
self.isUserInteractionEnabled = true
self.rightViewController?.endAppearanceTransition()
} }
rightContainer.state = .Closed
delegate?.sideNavDidCloseRightViewContainer?(self, container: rightContainer)
} }
/** /**
:name: switchMainViewController :name: switchMainViewController
*/ */
public func switchMainViewController(viewController: UIViewController, closeViewContainers: Bool) { public func switchMainViewController(viewController: UIViewController, closeViewContainers: Bool) {
removeViewController(mainViewController) removeViewController(&mainViewController)
mainViewController = viewController mainViewController = viewController
prepareContainedViewController(mainViewContainer, viewController: mainViewController) prepareContainedViewController(&mainViewContainer, viewController: &mainViewController)
if closeViewContainers { if closeViewContainers {
closeLeftViewContainer() closeLeftViewContainer()
closeRightViewContainer() closeRightViewContainer()
...@@ -405,9 +432,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -405,9 +432,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
:name: switchLeftViewController :name: switchLeftViewController
*/ */
public func switchLeftViewController(viewController: UIViewController, closeLeftViewContainerViewContainer: Bool) { public func switchLeftViewController(viewController: UIViewController, closeLeftViewContainerViewContainer: Bool) {
removeViewController(leftViewController) removeViewController(&leftViewController)
leftViewController = viewController leftViewController = viewController
prepareContainedViewController(leftViewContainer, viewController: leftViewController) prepareContainedViewController(&leftViewContainer, viewController: &leftViewController)
if closeLeftViewContainerViewContainer { if closeLeftViewContainerViewContainer {
closeLeftViewContainer() closeLeftViewContainer()
} }
...@@ -417,9 +444,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -417,9 +444,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
:name: switchRightViewController :name: switchRightViewController
*/ */
public func switchRightViewController(viewController: UIViewController, closeRightViewContainerViewContainer: Bool) { public func switchRightViewController(viewController: UIViewController, closeRightViewContainerViewContainer: Bool) {
removeViewController(rightViewController) removeViewController(&rightViewController)
rightViewController = viewController rightViewController = viewController
prepareContainedViewController(rightViewContainer, viewController: rightViewController) prepareContainedViewController(&rightViewContainer, viewController: &rightViewController)
if closeRightViewContainerViewContainer { if closeRightViewContainerViewContainer {
closeRightViewContainer() closeRightViewContainer()
} }
...@@ -450,10 +477,20 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -450,10 +477,20 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
internal func setupView() { internal func setupView() {
prepareMainContainer() prepareMainContainer()
prepareBackdropContainer() prepareBackdropContainer()
}
//
// :name: setupLeftView
//
internal func setupLeftView() {
prepareContainer(&leftContainer, viewContainer: &leftViewContainer, originX: leftOriginX, width: options.leftViewContainerWidth) prepareContainer(&leftContainer, viewContainer: &leftViewContainer, originX: leftOriginX, width: options.leftViewContainerWidth)
prepareLeftGestures() prepareLeftGestures()
}
//
// :name: setupRightView
//
internal func setupRightView() {
prepareContainer(&rightContainer, viewContainer: &rightViewContainer, originX: rightOriginX, width: options.rightViewContainerWidth) prepareContainer(&rightContainer, viewContainer: &rightViewContainer, originX: rightOriginX, width: options.rightViewContainerWidth)
prepareRightGestures() prepareRightGestures()
} }
...@@ -494,35 +531,43 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -494,35 +531,43 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
internal func handleLeftPanGesture(gesture: UIPanGestureRecognizer) { internal func handleLeftPanGesture(gesture: UIPanGestureRecognizer) {
if isRightContainerOpened { return } if isRightContainerOpened { return }
if .Began == gesture.state { if .Began == gesture.state {
leftContainer.state = isLeftContainerOpened ? .Opened : .Closed if let vc = leftViewContainer {
leftContainer.point = gesture.locationInView(view) if let c = leftContainer {
leftContainer.frame = leftViewContainer.frame leftViewController?.beginAppearanceTransition(!isLeftContainerOpened, animated: true)
delegate?.sideNavDidBeginLeftPan?(self, container: leftContainer) addShadow(&leftViewContainer)
leftViewController?.beginAppearanceTransition(!isLeftContainerOpened, animated: true) toggleWindow(shouldOpen: true)
addShadow(leftViewContainer) c.state = isLeftContainerOpened ? .Opened : .Closed
toggleWindow(shouldOpen: true) c.point = gesture.locationInView(view)
c.frame = vc.frame
delegate?.sideNavDidBeginLeftPan?(self, container: c)
}
}
} else if .Changed == gesture.state { } else if .Changed == gesture.state {
let v: CGPoint = gesture.translationInView(gesture.view!) if let vc = leftViewContainer {
let r = (leftViewContainer.frame.origin.x - leftOriginX) / leftViewContainer.frame.size.width if let c = leftContainer {
let s: CGFloat = 1 - (1 - options.contentViewScale) * r c.point = gesture.translationInView(gesture.view!)
let x: CGFloat = leftContainer.frame.origin.x + v.x let r = (vc.frame.origin.x - leftOriginX) / vc.frame.size.width
leftViewContainer.frame.origin.x = x < leftOriginX ? leftOriginX : x > 0 ? 0 : x let s: CGFloat = 1 - (1 - options.contentViewScale) * r
backdropViewContainer.layer.opacity = Float(r * options.contentViewOpacity) let x: CGFloat = c.frame.origin.x + c.point.x
mainViewContainer.transform = CGAffineTransformMakeScale(s, s) vc.frame.origin.x = x < leftOriginX ? leftOriginX : x > 0 ? 0 : x
if nil != delegate?.sideNavDidChangeLeftPan { backdropViewContainer?.layer.opacity = Float(r * options.contentViewOpacity)
delegate?.sideNavDidChangeLeftPan?(self, container: SideNavContainer(state: leftContainer.state, point: v, frame: leftContainer.frame)) mainViewContainer?.transform = CGAffineTransformMakeScale(s, s)
delegate?.sideNavDidChangeLeftPan?(self, container: c)
}
} }
} else { } else {
let v: CGPoint = gesture.velocityInView(gesture.view) if let vc = leftViewContainer {
let x: CGFloat = v.x >= 1000 || v.x <= -1000 ? v.x : 0 if let c = leftContainer {
let s: SideNavState = leftViewContainer.frame.origin.x <= CGFloat(floor(leftOriginX)) + options.pointOfNoReturnWidth || v.x <= -1000 ? .Closed : .Opened c.point = gesture.velocityInView(gesture.view)
if .Closed == s { let x: CGFloat = c.point.x >= 1000 || c.point.x <= -1000 ? c.point.x : 0
closeLeftViewContainer(velocity: x) c.state = vc.frame.origin.x <= CGFloat(floor(leftOriginX)) + options.pointOfNoReturnWidth || c.point.x <= -1000 ? .Closed : .Opened
} else { if .Closed == c.state {
openLeftViewContainer(velocity: x) closeLeftViewContainer(velocity: x)
} } else {
if nil != delegate?.sideNavDidEndLeftPan { openLeftViewContainer(velocity: x)
delegate?.sideNavDidEndLeftPan?(self, container: SideNavContainer(state: s, point: v, frame: leftContainer.frame)) }
delegate?.sideNavDidEndLeftPan?(self, container: c)
}
} }
} }
} }
...@@ -531,8 +576,10 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -531,8 +576,10 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// :name: handleLeftTapGesture // :name: handleLeftTapGesture
// //
internal func handleLeftTapGesture(gesture: UIPanGestureRecognizer) { internal func handleLeftTapGesture(gesture: UIPanGestureRecognizer) {
delegate?.sideNavDidTapLeft?(self, container: leftContainer) if let c = leftContainer {
closeLeftViewContainer() delegate?.sideNavDidTapLeft?(self, container: c)
closeLeftViewContainer()
}
} }
// //
...@@ -541,37 +588,44 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -541,37 +588,44 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
internal func handleRightPanGesture(gesture: UIPanGestureRecognizer) { internal func handleRightPanGesture(gesture: UIPanGestureRecognizer) {
if isLeftContainerOpened { return } if isLeftContainerOpened { return }
if .Began == gesture.state { if .Began == gesture.state {
rightContainer.state = isRightContainerOpened ? .Opened : .Closed if let vc = rightViewContainer {
rightContainer.point = gesture.locationInView(view) if let c = rightContainer {
rightContainer.frame = rightViewContainer.frame rightViewController?.beginAppearanceTransition(!isRightContainerOpened, animated: true)
delegate?.sideNavDidBeginRightPan?(self, container: rightContainer) addShadow(&rightViewContainer)
rightViewController?.beginAppearanceTransition(!isRightContainerOpened, animated: true) toggleWindow(shouldOpen: true)
addShadow(rightViewContainer) c.state = isRightContainerOpened ? .Opened : .Closed
toggleWindow(shouldOpen: true) c.point = gesture.locationInView(view)
c.frame = vc.frame
delegate?.sideNavDidBeginRightPan?(self, container: c)
}
}
} else if .Changed == gesture.state { } else if .Changed == gesture.state {
let v: CGPoint = gesture.translationInView(gesture.view!) if let vc = rightViewContainer {
if let c = rightContainer {
let r = (rightOriginX - rightViewContainer.frame.origin.x) / rightViewContainer.frame.size.width c.point = gesture.translationInView(gesture.view!)
let s: CGFloat = 1 - (1 - options.contentViewScale) * r let r = (rightOriginX - vc.frame.origin.x) / vc.frame.size.width
let m: CGFloat = rightOriginX - rightViewContainer.frame.size.width let s: CGFloat = 1 - (1 - options.contentViewScale) * r
let x: CGFloat = rightContainer.frame.origin.x + gesture.translationInView(gesture.view!).x let m: CGFloat = rightOriginX - vc.frame.size.width
rightViewContainer.frame.origin.x = x > rightOriginX ? rightOriginX : x < m ? m : x let x: CGFloat = c.frame.origin.x + c.point.x
backdropViewContainer.layer.opacity = Float(r * options.contentViewOpacity) vc.frame.origin.x = x > rightOriginX ? rightOriginX : x < m ? m : x
mainViewContainer.transform = CGAffineTransformMakeScale(s, s) backdropViewContainer?.layer.opacity = Float(r * options.contentViewOpacity)
if nil != delegate?.sideNavDidChangeRightPan { mainViewContainer?.transform = CGAffineTransformMakeScale(s, s)
delegate?.sideNavDidChangeRightPan?(self, container: SideNavContainer(state: rightContainer.state, point: v, frame: rightContainer.frame)) delegate?.sideNavDidChangeRightPan?(self, container: c)
}
} }
} else { } else {
let v: CGPoint = gesture.velocityInView(gesture.view) if let vc = rightViewContainer {
let x: CGFloat = v.x <= -1000 || v.x >= 1000 ? v.x : 0 if let c = rightContainer {
let s: SideNavState = rightViewContainer.frame.origin.x >= CGFloat(floor(rightOriginX) - options.pointOfNoReturnWidth) || v.x >= 1000 ? .Closed : .Opened c.point = gesture.velocityInView(gesture.view)
if .Closed == s { let x: CGFloat = c.point.x <= -1000 || c.point.x >= 1000 ? c.point.x : 0
closeRightViewContainer(velocity: x) c.state = vc.frame.origin.x >= CGFloat(floor(rightOriginX) - options.pointOfNoReturnWidth) || c.point.x >= 1000 ? .Closed : .Opened
} else { if .Closed == c.state {
openRightViewContainer(velocity: x) closeRightViewContainer(velocity: x)
} } else {
if nil != delegate?.sideNavDidEndRightPan { openRightViewContainer(velocity: x)
delegate?.sideNavDidEndRightPan?(self, container: SideNavContainer(state: s, point: v, frame: rightContainer.frame)) }
delegate?.sideNavDidEndRightPan?(self, container: c)
}
} }
} }
} }
...@@ -580,27 +634,33 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -580,27 +634,33 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// :name: handleRightTapGesture // :name: handleRightTapGesture
// //
internal func handleRightTapGesture(gesture: UIPanGestureRecognizer) { internal func handleRightTapGesture(gesture: UIPanGestureRecognizer) {
delegate?.sideNavDidTapRight?(self, container: rightContainer) if let c = rightContainer {
closeRightViewContainer() delegate?.sideNavDidTapRight?(self, container: c)
closeRightViewContainer()
}
} }
// //
// :name: addShadow // :name: addShadow
// //
private func addShadow(container: UIView) { private func addShadow(inout viewContainer: UIView?) {
container.layer.shadowOffset = options.shadowOffset if let vc = viewContainer {
container.layer.shadowOpacity = options.shadowOpacity vc.layer.shadowOffset = options.shadowOffset
container.layer.shadowRadius = options.shadowRadius vc.layer.shadowOpacity = options.shadowOpacity
container.layer.shadowPath = UIBezierPath(rect: container.bounds).CGPath vc.layer.shadowRadius = options.shadowRadius
container.layer.masksToBounds = false vc.layer.shadowPath = UIBezierPath(rect: vc.bounds).CGPath
vc.layer.masksToBounds = false
}
} }
// //
// :name: removeShadow // :name: removeShadow
// //
private func removeShadow(container: UIView) { private func removeShadow(inout viewContainer: UIView?) {
container.layer.opacity = 1 if let vc = viewContainer {
container.layer.masksToBounds = true vc.layer.opacity = 1
vc.layer.masksToBounds = true
}
} }
// //
...@@ -623,7 +683,7 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -623,7 +683,7 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
// :name: removeViewController // :name: removeViewController
// //
private func removeViewController(viewController: UIViewController?) { private func removeViewController(inout viewController: UIViewController?) {
if let vc = viewController { if let vc = viewController {
vc.willMoveToParentViewController(nil) vc.willMoveToParentViewController(nil)
vc.view.removeFromSuperview() vc.view.removeFromSuperview()
...@@ -670,8 +730,11 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -670,8 +730,11 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
// :name: isPointContainedWithinViewController // :name: isPointContainedWithinViewController
// //
private func isPointContainedWithinViewController(inout viewContainer: UIView!, point: CGPoint) -> Bool { private func isPointContainedWithinViewController(inout viewContainer: UIView?, point: CGPoint) -> Bool {
return CGRectContainsPoint(viewContainer.frame, point) if let vc = viewContainer {
return CGRectContainsPoint(vc.frame, point)
}
return false
} }
// //
...@@ -679,9 +742,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -679,9 +742,9 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
private func prepareMainContainer() { private func prepareMainContainer() {
mainViewContainer = UIView(frame: view.bounds) mainViewContainer = UIView(frame: view.bounds)
mainViewContainer.backgroundColor = .clearColor() mainViewContainer!.backgroundColor = .clearColor()
mainViewContainer.autoresizingMask = .FlexibleHeight | .FlexibleWidth mainViewContainer!.autoresizingMask = .FlexibleHeight | .FlexibleWidth
view.addSubview(mainViewContainer) view.addSubview(mainViewContainer!)
} }
// //
...@@ -689,10 +752,10 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -689,10 +752,10 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
private func prepareBackdropContainer() { private func prepareBackdropContainer() {
backdropViewContainer = UIView(frame: view.bounds) backdropViewContainer = UIView(frame: view.bounds)
backdropViewContainer.backgroundColor = options.backdropViewContainerBackgroundColor backdropViewContainer!.backgroundColor = options.backdropViewContainerBackgroundColor
backdropViewContainer.autoresizingMask = .FlexibleHeight | .FlexibleWidth backdropViewContainer!.autoresizingMask = .FlexibleHeight | .FlexibleWidth
backdropViewContainer.layer.opacity = 0 backdropViewContainer!.layer.opacity = 0
view.addSubview(backdropViewContainer) view.addSubview(backdropViewContainer!)
} }
// //
...@@ -706,15 +769,15 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -706,15 +769,15 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
// :name: prepareContainer // :name: prepareContainer
// //
private func prepareContainer(inout container: SideNavContainer!, inout viewContainer: UIView!, originX: CGFloat, width: CGFloat) { private func prepareContainer(inout container: SideNavContainer?, inout viewContainer: UIView?, originX: CGFloat, width: CGFloat) {
container = SideNavContainer(state: .Closed, point: CGPointZero, frame: CGRectZero) container = SideNavContainer(state: .Closed, point: CGPointZero, frame: CGRectZero)
var b: CGRect = view.bounds var b: CGRect = view.bounds
b.size.width = width b.size.width = width
b.origin.x = originX b.origin.x = originX
viewContainer = UIView(frame: b) viewContainer = UIView(frame: b)
viewContainer.backgroundColor = .clearColor() viewContainer!.backgroundColor = .clearColor()
viewContainer.autoresizingMask = .FlexibleHeight viewContainer!.autoresizingMask = .FlexibleHeight
view.addSubview(viewContainer) view.addSubview(viewContainer!)
} }
// //
...@@ -728,33 +791,31 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg ...@@ -728,33 +791,31 @@ public class SideNavController: MaterialViewController, UIGestureRecognizerDeleg
// //
// :name: prepareContainerToOpen // :name: prepareContainerToOpen
// //
private func prepareContainerToOpen(inout viewController: UIViewController?, inout viewContainer: UIView!, state: SideNavState) { private func prepareContainerToOpen(inout viewController: UIViewController?, inout viewContainer: UIView?, state: SideNavState) {
if let vc = viewController { viewController?.beginAppearanceTransition(.Opened == state, animated: true)
vc.beginAppearanceTransition(.Opened == state, animated: true) addShadow(&viewContainer)
addShadow(viewContainer) toggleWindow(shouldOpen: true)
toggleWindow(shouldOpen: true)
}
} }
// //
// :name: prepareContainerToClose // :name: prepareContainerToClose
// //
private func prepareContainerToClose(inout viewController: UIViewController?, state: SideNavState) { private func prepareContainerToClose(inout viewController: UIViewController?, state: SideNavState) {
if let vc = viewController { viewController?.beginAppearanceTransition(.Opened == state, animated: true)
vc.beginAppearanceTransition(.Opened == state, animated: true) toggleWindow()
toggleWindow()
}
} }
// //
// :name: prepareContainedViewController // :name: prepareContainedViewController
// //
private func prepareContainedViewController(container: UIView, viewController: UIViewController?) { private func prepareContainedViewController(inout viewContainer: UIView?, inout viewController: UIViewController?) {
if let vc = viewController { if let vc = viewController {
addChildViewController(vc) if let c = viewContainer {
vc.view.frame = container.bounds addChildViewController(vc)
container.addSubview(vc.view) vc.view.frame = c.bounds
vc.didMoveToParentViewController(self) c.addSubview(vc.view)
vc.didMoveToParentViewController(self)
}
} }
} }
} }
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