Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
Material
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
Material
Commits
95248a7e
Commit
95248a7e
authored
Aug 26, 2015
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'issue-5' into development
parents
339e153e
17c1d27f
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
852 additions
and
0 deletions
+852
-0
MaterialKit.xcodeproj/project.pbxproj
+12
-0
Source/SideNavController.swift
+840
-0
No files found.
MaterialKit.xcodeproj/project.pbxproj
View file @
95248a7e
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
65B965721B8A578D0055B139
/* MaterialViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B965711B8A578D0055B139
/* MaterialViewController.swift */
;
};
65B965721B8A578D0055B139
/* MaterialViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B965711B8A578D0055B139
/* MaterialViewController.swift */
;
};
65B965751B8A60A00055B139
/* MaterialView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B965741B8A60A00055B139
/* MaterialView.swift */
;
};
65B965751B8A60A00055B139
/* MaterialView.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B965741B8A60A00055B139
/* MaterialView.swift */
;
};
65B9657E1B8A7C330055B139
/* MaterialButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B9657D1B8A7C330055B139
/* MaterialButton.swift */
;
};
65B9657E1B8A7C330055B139
/* MaterialButton.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B9657D1B8A7C330055B139
/* MaterialButton.swift */
;
};
65B965871B8BEEC60055B139
/* SideNavController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
65B965861B8BEEC60055B139
/* SideNavController.swift */
;
};
963832421B88DFD80015F710
/* MaterialKit.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
963832361B88DFD80015F710
/* MaterialKit.framework */
;
};
963832421B88DFD80015F710
/* MaterialKit.framework in Frameworks */
=
{
isa
=
PBXBuildFile
;
fileRef
=
963832361B88DFD80015F710
/* MaterialKit.framework */
;
};
9638325A1B88E31A0015F710
/* MaterialKitTests.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
963832581B88E31A0015F710
/* MaterialKitTests.swift */
;
};
9638325A1B88E31A0015F710
/* MaterialKitTests.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
963832581B88E31A0015F710
/* MaterialKitTests.swift */
;
};
963832691B88E5BF0015F710
/* Capture.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
9638325E1B88E5BF0015F710
/* Capture.swift */
;
};
963832691B88E5BF0015F710
/* Capture.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
9638325E1B88E5BF0015F710
/* Capture.swift */
;
};
...
@@ -56,6 +57,7 @@
...
@@ -56,6 +57,7 @@
65B965711B8A578D0055B139
/* MaterialViewController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MaterialViewController.swift
;
sourceTree
=
"<group>"
;
};
65B965711B8A578D0055B139
/* MaterialViewController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MaterialViewController.swift
;
sourceTree
=
"<group>"
;
};
65B965741B8A60A00055B139
/* MaterialView.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MaterialView.swift
;
sourceTree
=
"<group>"
;
};
65B965741B8A60A00055B139
/* MaterialView.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MaterialView.swift
;
sourceTree
=
"<group>"
;
};
65B9657D1B8A7C330055B139
/* MaterialButton.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MaterialButton.swift
;
sourceTree
=
"<group>"
;
};
65B9657D1B8A7C330055B139
/* MaterialButton.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MaterialButton.swift
;
sourceTree
=
"<group>"
;
};
65B965861B8BEEC60055B139
/* SideNavController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SideNavController.swift
;
sourceTree
=
"<group>"
;
};
963832361B88DFD80015F710
/* MaterialKit.framework */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
wrapper.framework
;
includeInIndex
=
0
;
path
=
MaterialKit.framework
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
963832361B88DFD80015F710
/* MaterialKit.framework */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
wrapper.framework
;
includeInIndex
=
0
;
path
=
MaterialKit.framework
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
963832411B88DFD80015F710
/* MaterialKitTests.xctest */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
wrapper.cfbundle
;
includeInIndex
=
0
;
path
=
MaterialKitTests.xctest
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
963832411B88DFD80015F710
/* MaterialKitTests.xctest */
=
{
isa
=
PBXFileReference
;
explicitFileType
=
wrapper.cfbundle
;
includeInIndex
=
0
;
path
=
MaterialKitTests.xctest
;
sourceTree
=
BUILT_PRODUCTS_DIR
;
};
963832541B88E30F0015F710
/* Info.plist */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.plist.xml
;
path
=
Info.plist
;
sourceTree
=
"<group>"
;
};
963832541B88E30F0015F710
/* Info.plist */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
text.plist.xml
;
path
=
Info.plist
;
sourceTree
=
"<group>"
;
};
...
@@ -109,6 +111,14 @@
...
@@ -109,6 +111,14 @@
name
=
View
;
name
=
View
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
};
};
65B965851B8BEEB00055B139
/* Nav */
=
{
isa
=
PBXGroup
;
children
=
(
65B965861B8BEEC60055B139
/* SideNavController.swift */
,
);
name
=
Nav
;
sourceTree
=
"<group>"
;
};
9638322C1B88DFD80015F710
=
{
9638322C1B88DFD80015F710
=
{
isa
=
PBXGroup
;
isa
=
PBXGroup
;
children
=
(
children
=
(
...
@@ -135,6 +145,7 @@
...
@@ -135,6 +145,7 @@
9AAC38521B89553800FE6B2D
/* Font */
,
9AAC38521B89553800FE6B2D
/* Font */
,
963832861B8907FE0015F710
/* Layout */
,
963832861B8907FE0015F710
/* Layout */
,
65B965731B8A58E60055B139
/* View */
,
65B965731B8A58E60055B139
/* View */
,
65B965851B8BEEB00055B139
/* Nav */
,
963832761B88E8990015F710
/* Text */
,
963832761B88E8990015F710
/* Text */
,
963832751B88E87B0015F710
/* Button */
,
963832751B88E87B0015F710
/* Button */
,
9AAC384B1B89524E00FE6B2D
/* Card */
,
9AAC384B1B89524E00FE6B2D
/* Card */
,
...
@@ -351,6 +362,7 @@
...
@@ -351,6 +362,7 @@
9A94D10B1B8A485C00F586A5
/* ImageCard.swift in Sources */
,
9A94D10B1B8A485C00F586A5
/* ImageCard.swift in Sources */
,
9638326B1B88E5BF0015F710
/* FabButton.swift in Sources */
,
9638326B1B88E5BF0015F710
/* FabButton.swift in Sources */
,
9A94D1091B8A3F5100F586A5
/* MaterialPulseView.swift in Sources */
,
9A94D1091B8A3F5100F586A5
/* MaterialPulseView.swift in Sources */
,
65B965871B8BEEC60055B139
/* SideNavController.swift in Sources */
,
9638326C1B88E5BF0015F710
/* FlatButton.swift in Sources */
,
9638326C1B88E5BF0015F710
/* FlatButton.swift in Sources */
,
65B965751B8A60A00055B139
/* MaterialView.swift in Sources */
,
65B965751B8A60A00055B139
/* MaterialView.swift in Sources */
,
963832711B88E5BF0015F710
/* Text.swift in Sources */
,
963832711B88E5BF0015F710
/* Text.swift in Sources */
,
...
...
Source/SideNavController.swift
0 → 100644
View file @
95248a7e
//
// 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
enum
SideNavState
{
case
Opened
case
Closed
}
@objc(SideNavContainer)
public
class
SideNavContainer
:
Printable
{
public
private(set)
var
state
:
SideNavState
public
private(set)
var
point
:
CGPoint
public
private(set)
var
frame
:
CGRect
public
var
description
:
String
{
let
s
:
String
=
.
Opened
==
state
?
"Opened"
:
"Closed"
return
"(state:
\(
s
)
, point:
\(
point
)
, frame:
\(
frame
)
)"
}
public
init
(
state
:
SideNavState
,
point
:
CGPoint
,
frame
:
CGRect
)
{
self
.
state
=
state
self
.
point
=
point
self
.
frame
=
frame
}
}
@objc(SideNavDelegate)
public
protocol
SideNavDelegate
{
// left
optional
func
sideNavDidBeginLeftPan
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidChangeLeftPan
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidEndLeftPan
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidOpenLeftViewContainer
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidCloseLeftViewContainer
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidTapLeft
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
// right
optional
func
sideNavDidBeginRightPan
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidChangeRightPan
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidEndRightPan
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidOpenRightViewContainer
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidCloseRightViewContainer
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
optional
func
sideNavDidTapRight
(
sideNav
:
SideNavController
,
container
:
SideNavContainer
)
}
@objc(SideNavController)
public
class
SideNavController
:
MaterialViewController
,
UIGestureRecognizerDelegate
{
/**
: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
contentViewScale
:
CGFloat
=
1
public
static
var
contentViewOpacity
:
CGFloat
=
0.4
public
static
var
shouldHideStatusBar
:
Bool
=
true
public
static
var
pointOfNoReturnWidth
:
CGFloat
=
48
public
static
var
backdropViewContainerBackgroundColor
:
UIColor
=
.
blackColor
()
public
static
var
animationDuration
:
CGFloat
=
0.5
public
static
var
leftBezelWidth
:
CGFloat
=
16
public
static
var
leftViewContainerWidth
:
CGFloat
=
270
public
static
var
leftPanFromBezel
:
Bool
=
true
public
static
var
rightBezelWidth
:
CGFloat
=
16
public
static
var
rightViewContainerWidth
:
CGFloat
=
270
public
static
var
rightPanFromBezel
:
Bool
=
true
}
/**
:name: delegate
*/
public
weak
var
delegate
:
SideNavDelegate
?
/**
:name: isViewBasedAppearance
*/
public
var
isViewBasedAppearance
:
Bool
{
return
0
==
NSBundle
.
mainBundle
()
.
objectForInfoDictionaryKey
(
"UIViewControllerBasedStatusBarAppearance"
)
as?
Int
}
/**
:name: isLeftContainerOpened
*/
public
var
isLeftContainerOpened
:
Bool
{
return
0
==
leftViewContainer
.
frame
.
origin
.
x
}
/**
:name: isRightContainerOpened
*/
public
var
isRightContainerOpened
:
Bool
{
return
rightViewContainer
.
frame
.
origin
.
x
==
rightOrigin
-
rightViewContainer
.
frame
.
size
.
width
}
/**
:name: isUserInteractionEnabled
*/
public
private(set)
var
isUserInteractionEnabled
:
Bool
{
get
{
return
mainViewContainer
.
userInteractionEnabled
}
set
(
value
)
{
mainViewContainer
.
userInteractionEnabled
=
value
}
}
/**
:name: backdropViewContainer
*/
public
private(set)
var
backdropViewContainer
:
UIView
!
/**
:name: mainViewContainer
*/
public
private(set)
var
mainViewContainer
:
UIView
!
/**
:name: leftViewContainer
*/
public
private(set)
var
leftViewContainer
:
UIView
!
/**
:name: rightViewContainer
*/
public
private(set)
var
rightViewContainer
:
UIView
!
/**
:name: leftContainer
*/
public
private(set)
var
leftContainer
:
SideNavContainer
!
/**
:name: rightContainer
*/
public
private(set)
var
rightContainer
:
SideNavContainer
!
/**
:name: mainViewController
*/
public
var
mainViewController
:
UIViewController
?
/**
:name: leftViewController
*/
public
var
leftViewController
:
UIViewController
?
/**
:name: rightViewController
*/
public
var
rightViewController
:
UIViewController
?
/**
:name: leftPanGesture
*/
public
var
leftPanGesture
:
UIPanGestureRecognizer
?
/**
:name: leftTapGetsture
*/
public
var
leftTapGetsture
:
UITapGestureRecognizer
?
/**
:name: rightPanGesture
*/
public
var
rightPanGesture
:
UIPanGestureRecognizer
?
/**
:name: rightTapGesture
*/
public
var
rightTapGesture
:
UITapGestureRecognizer
?
//
// :name: leftOrigin
//
private
var
leftOrigin
:
CGFloat
{
return
-
options
.
leftViewContainerWidth
}
//
// :name: rightOrigin
//
private
var
rightOrigin
:
CGFloat
{
return
view
.
bounds
.
width
}
/**
: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
,
leftViewController
:
UIViewController
)
{
self
.
init
()
self
.
mainViewController
=
mainViewController
self
.
leftViewController
=
leftViewController
setupView
()
}
/**
:name: init
*/
public
convenience
init
(
mainViewController
:
UIViewController
,
rightViewController
:
UIViewController
)
{
self
.
init
()
self
.
mainViewController
=
mainViewController
self
.
rightViewController
=
rightViewController
setupView
()
}
/**
:name: init
*/
public
convenience
init
(
mainViewController
:
UIViewController
,
leftViewController
:
UIViewController
,
rightViewController
:
UIViewController
)
{
self
.
init
()
self
.
mainViewController
=
mainViewController
self
.
leftViewController
=
leftViewController
self
.
rightViewController
=
rightViewController
setupView
()
}
//
// :name: viewDidLoad
//
public
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
edgesForExtendedLayout
=
.
None
}
//
// :name: viewWillLayoutSubviews
//
public
override
func
viewWillLayoutSubviews
()
{
prepareContainedViewController
(
mainViewContainer
,
viewController
:
mainViewController
)
prepareContainedViewController
(
leftViewContainer
,
viewController
:
leftViewController
)
prepareContainedViewController
(
rightViewContainer
,
viewController
:
rightViewController
)
}
//
// :name: viewWillTransitionToSize
//
public
override
func
viewWillTransitionToSize
(
size
:
CGSize
,
withTransitionCoordinator
coordinator
:
UIViewControllerTransitionCoordinator
)
{
super
.
viewWillTransitionToSize
(
size
,
withTransitionCoordinator
:
coordinator
)
mainViewContainer
.
transform
=
CGAffineTransformMakeScale
(
1
,
1
)
leftViewContainer
.
hidden
=
true
rightViewContainer
.
hidden
=
true
coordinator
.
animateAlongsideTransition
(
nil
)
{
_
in
self
.
closeWindow
()
self
.
backdropViewContainer
.
layer
.
opacity
=
0
self
.
mainViewContainer
.
transform
=
CGAffineTransformMakeScale
(
1
,
1
)
self
.
isUserInteractionEnabled
=
true
self
.
leftViewContainer
.
frame
.
origin
.
x
=
self
.
leftOrigin
self
.
leftViewContainer
.
hidden
=
false
self
.
removeShadow
(
self
.
leftViewContainer
)
self
.
prepareLeftGestures
()
self
.
rightViewContainer
.
frame
.
origin
.
x
=
self
.
rightOrigin
self
.
rightViewContainer
.
hidden
=
false
self
.
removeShadow
(
self
.
rightViewContainer
)
self
.
prepareRightGestures
()
}
}
/**
:name: toggleLeftViewContainer
*/
public
func
toggleLeftViewContainer
(
velocity
:
CGFloat
=
0
)
{
isLeftContainerOpened
?
closeLeftViewContainer
(
velocity
:
velocity
)
:
openLeftViewContainer
(
velocity
:
velocity
)
}
/**
:name: toggleRightViewContainer
*/
public
func
toggleRightViewContainer
(
velocity
:
CGFloat
=
0
)
{
isRightContainerOpened
?
closeRightViewContainer
(
velocity
:
velocity
)
:
openRightViewContainer
(
velocity
:
velocity
)
}
/**
:name: openLeftViewContainer
*/
public
func
openLeftViewContainer
(
velocity
:
CGFloat
=
0
)
{
prepareLeftContainerToOpen
()
UIView
.
animateWithDuration
(
Double
(
0
==
velocity
?
options
.
animationDuration
:
fmax
(
0.1
,
fmin
(
1
,
Double
(
leftViewContainer
.
frame
.
origin
.
x
/
velocity
)))),
delay
:
0
,
options
:
.
CurveEaseInOut
,
animations
:
{
_
in
self
.
leftViewContainer
.
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
()
}
leftContainer
.
state
=
.
Opened
delegate
?
.
sideNavDidOpenLeftViewContainer
?(
self
,
container
:
leftContainer
)
}
/**
:name: openRightViewContainer
*/
public
func
openRightViewContainer
(
velocity
:
CGFloat
=
0
)
{
prepareRightContainerToOpen
()
UIView
.
animateWithDuration
(
Double
(
0
==
velocity
?
options
.
animationDuration
:
fmax
(
0.1
,
fmin
(
1
,
Double
(
fabs
(
rightViewContainer
.
frame
.
origin
.
x
-
rightOrigin
)
/
velocity
)))),
delay
:
0
,
options
:
.
CurveEaseInOut
,
animations
:
{
_
in
self
.
rightViewContainer
.
frame
.
origin
.
x
=
self
.
rightOrigin
-
self
.
rightViewContainer
.
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
()
}
rightContainer
.
state
=
.
Opened
delegate
?
.
sideNavDidOpenRightViewContainer
?(
self
,
container
:
rightContainer
)
}
/**
:name: closeLeftViewContainer
*/
public
func
closeLeftViewContainer
(
velocity
:
CGFloat
=
0
)
{
prepareLeftContainerToClose
()
UIView
.
animateWithDuration
(
Double
(
0
==
velocity
?
options
.
animationDuration
:
fmax
(
0.1
,
fmin
(
1
,
fabs
(
leftViewContainer
.
frame
.
origin
.
x
-
leftOrigin
)
/
velocity
))),
delay
:
0
,
options
:
.
CurveEaseInOut
,
animations
:
{
_
in
self
.
leftViewContainer
.
frame
.
origin
.
x
=
self
.
leftOrigin
self
.
backdropViewContainer
.
layer
.
opacity
=
0
self
.
mainViewContainer
.
transform
=
CGAffineTransformMakeScale
(
1
,
1
)
}
)
{
_
in
self
.
removeShadow
(
self
.
leftViewContainer
)
self
.
isUserInteractionEnabled
=
true
self
.
leftViewController
?
.
endAppearanceTransition
()
}
leftContainer
.
state
=
.
Closed
delegate
?
.
sideNavDidCloseLeftViewContainer
?(
self
,
container
:
leftContainer
)
}
/**
:name: closeRightViewContainer
*/
public
func
closeRightViewContainer
(
velocity
:
CGFloat
=
0
)
{
prepareRightContainerToClose
()
UIView
.
animateWithDuration
(
Double
(
0
==
velocity
?
options
.
animationDuration
:
fmax
(
0.1
,
fmin
(
1
,
fabs
(
rightViewContainer
.
frame
.
origin
.
x
-
rightOrigin
)
/
velocity
))),
delay
:
0
,
options
:
.
CurveEaseInOut
,
animations
:
{
_
in
self
.
rightViewContainer
.
frame
.
origin
.
x
=
self
.
rightOrigin
self
.
backdropViewContainer
.
layer
.
opacity
=
0
self
.
mainViewContainer
.
transform
=
CGAffineTransformMakeScale
(
1
,
1
)
}
)
{
_
in
self
.
removeShadow
(
self
.
rightViewContainer
)
self
.
isUserInteractionEnabled
=
true
self
.
rightViewController
?
.
endAppearanceTransition
()
}
rightContainer
.
state
=
.
Closed
delegate
?
.
sideNavDidCloseRightViewContainer
?(
self
,
container
:
rightContainer
)
}
/**
:name: switchMainViewController
*/
public
func
switchMainViewController
(
viewController
:
UIViewController
,
closeViewContainers
:
Bool
)
{
removeViewController
(
mainViewController
)
mainViewController
=
viewController
prepareContainedViewController
(
mainViewContainer
,
viewController
:
mainViewController
)
if
closeViewContainers
{
closeLeftViewContainer
()
closeRightViewContainer
()
}
}
/**
:name: switchLeftViewController
*/
public
func
switchLeftViewController
(
viewController
:
UIViewController
,
closeLeftViewContainerViewContainer
:
Bool
)
{
removeViewController
(
leftViewController
)
leftViewController
=
viewController
prepareContainedViewController
(
leftViewContainer
,
viewController
:
leftViewController
)
if
closeLeftViewContainerViewContainer
{
closeLeftViewContainer
()
}
}
/**
:name: switchRightViewController
*/
public
func
switchRightViewController
(
viewController
:
UIViewController
,
closeRightViewContainerViewContainer
:
Bool
)
{
removeViewController
(
rightViewController
)
rightViewController
=
viewController
prepareContainedViewController
(
rightViewContainer
,
viewController
:
rightViewController
)
if
closeRightViewContainerViewContainer
{
closeRightViewContainer
()
}
}
//
// :name: gestureRecognizer
//
public
func
gestureRecognizer
(
gestureRecognizer
:
UIGestureRecognizer
,
shouldReceiveTouch
touch
:
UITouch
)
->
Bool
{
if
gestureRecognizer
==
leftPanGesture
{
return
gesturePanLeftViewController
(
gestureRecognizer
,
point
:
touch
.
locationInView
(
view
))
}
if
gestureRecognizer
==
rightPanGesture
{
return
gesturePanRightViewController
(
gestureRecognizer
,
withTouchPoint
:
touch
.
locationInView
(
view
))
}
if
gestureRecognizer
==
leftTapGetsture
{
return
isLeftContainerOpened
&&
!
isPointContainedWithinLeftRectViewController
(
touch
.
locationInView
(
view
))
}
if
gestureRecognizer
==
rightTapGesture
{
return
isRightContainerOpened
&&
!
isPointContainedWithinRightViewController
(
touch
.
locationInView
(
view
))
}
return
true
}
//
// :name: setupView
//
internal
func
setupView
()
{
prepareMainContainer
()
prepareBackdropContainer
()
prepareLeftContainer
()
prepareLeftGestures
()
prepareRightContainer
()
prepareRightGestures
()
}
//
// :name: addLeftGestures
//
private
func
addLeftGestures
()
{
if
nil
==
leftPanGesture
{
leftPanGesture
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
"handleLeftPanGesture:"
)
leftPanGesture
!.
delegate
=
self
view
.
addGestureRecognizer
(
leftPanGesture
!
)
}
if
nil
==
leftTapGetsture
{
leftTapGetsture
=
UITapGestureRecognizer
(
target
:
self
,
action
:
"handleLeftTapGesture:"
)
leftTapGetsture
!.
delegate
=
self
view
.
addGestureRecognizer
(
leftTapGetsture
!
)
}
}
//
// :name: addRightGestures
//
private
func
addRightGestures
()
{
if
nil
==
rightPanGesture
{
rightPanGesture
=
UIPanGestureRecognizer
(
target
:
self
,
action
:
"handleRightPanGesture:"
)
rightPanGesture
!.
delegate
=
self
view
.
addGestureRecognizer
(
rightPanGesture
!
)
}
if
nil
==
rightTapGesture
{
rightTapGesture
=
UITapGestureRecognizer
(
target
:
self
,
action
:
"handleRightTapGesture:"
)
rightTapGesture
!.
delegate
=
self
view
.
addGestureRecognizer
(
rightTapGesture
!
)
}
}
//
// :name: removeLeftGestures
//
private
func
removeLeftGestures
()
{
if
let
l
=
leftPanGesture
{
view
.
removeGestureRecognizer
(
l
)
leftPanGesture
=
nil
}
if
let
l
=
leftTapGetsture
{
view
.
removeGestureRecognizer
(
l
)
leftTapGetsture
=
nil
}
}
//
// :name: removeRightGestures
//
private
func
removeRightGestures
()
{
if
let
r
=
rightPanGesture
{
view
.
removeGestureRecognizer
(
r
)
rightPanGesture
=
nil
}
if
let
r
=
rightTapGesture
{
view
.
removeGestureRecognizer
(
r
)
rightTapGesture
=
nil
}
}
//
// :name: handleLeftPanGesture
//
internal
func
handleLeftPanGesture
(
gesture
:
UIPanGestureRecognizer
)
{
if
isRightContainerOpened
{
return
}
if
.
Began
==
gesture
.
state
{
leftContainer
.
state
=
isLeftContainerOpened
?
.
Opened
:
.
Closed
leftContainer
.
point
=
gesture
.
locationInView
(
view
)
leftContainer
.
frame
=
leftViewContainer
.
frame
delegate
?
.
sideNavDidBeginLeftPan
?(
self
,
container
:
leftContainer
)
leftViewController
?
.
beginAppearanceTransition
(
!
isLeftContainerOpened
,
animated
:
true
)
addShadow
(
leftViewContainer
)
openWindow
()
}
else
if
.
Changed
==
gesture
.
state
{
let
v
:
CGPoint
=
gesture
.
translationInView
(
gesture
.
view
!
)
let
r
=
(
leftViewContainer
.
frame
.
origin
.
x
-
leftOrigin
)
/
leftViewContainer
.
frame
.
size
.
width
let
s
:
CGFloat
=
1
-
(
1
-
options
.
contentViewScale
)
*
r
let
x
:
CGFloat
=
leftContainer
.
frame
.
origin
.
x
+
v
.
x
leftViewContainer
.
frame
.
origin
.
x
=
x
<
leftOrigin
?
leftOrigin
:
x
>
0
?
0
:
x
backdropViewContainer
.
layer
.
opacity
=
Float
(
r
*
options
.
contentViewOpacity
)
mainViewContainer
.
transform
=
CGAffineTransformMakeScale
(
s
,
s
)
if
nil
!=
delegate
?
.
sideNavDidChangeLeftPan
{
delegate
?
.
sideNavDidChangeLeftPan
?(
self
,
container
:
SideNavContainer
(
state
:
leftContainer
.
state
,
point
:
v
,
frame
:
leftContainer
.
frame
))
}
}
else
{
let
v
:
CGPoint
=
gesture
.
velocityInView
(
gesture
.
view
)
let
x
:
CGFloat
=
v
.
x
>=
1000
||
v
.
x
<=
-
1000
?
v
.
x
:
0
let
s
:
SideNavState
=
leftViewContainer
.
frame
.
origin
.
x
<=
CGFloat
(
floor
(
leftOrigin
))
+
options
.
pointOfNoReturnWidth
||
v
.
x
<=
-
1000
?
.
Closed
:
.
Opened
if
.
Closed
==
s
{
closeLeftViewContainer
(
velocity
:
x
)
}
else
{
openLeftViewContainer
(
velocity
:
x
)
}
if
nil
!=
delegate
?
.
sideNavDidEndLeftPan
{
delegate
?
.
sideNavDidEndLeftPan
?(
self
,
container
:
SideNavContainer
(
state
:
s
,
point
:
v
,
frame
:
leftContainer
.
frame
))
}
}
}
//
// :name: handleLeftTapGesture
//
internal
func
handleLeftTapGesture
(
gesture
:
UIPanGestureRecognizer
)
{
delegate
?
.
sideNavDidTapLeft
?(
self
,
container
:
leftContainer
)
closeLeftViewContainer
()
}
//
// :name: handleRightPanGesture
//
internal
func
handleRightPanGesture
(
gesture
:
UIPanGestureRecognizer
)
{
if
isLeftContainerOpened
{
return
}
if
.
Began
==
gesture
.
state
{
rightContainer
.
state
=
isRightContainerOpened
?
.
Opened
:
.
Closed
rightContainer
.
point
=
gesture
.
locationInView
(
view
)
rightContainer
.
frame
=
rightViewContainer
.
frame
delegate
?
.
sideNavDidBeginRightPan
?(
self
,
container
:
rightContainer
)
rightViewController
?
.
beginAppearanceTransition
(
!
isRightContainerOpened
,
animated
:
true
)
addShadow
(
rightViewContainer
)
openWindow
()
}
else
if
.
Changed
==
gesture
.
state
{
let
v
:
CGPoint
=
gesture
.
translationInView
(
gesture
.
view
!
)
let
r
=
(
rightOrigin
-
rightViewContainer
.
frame
.
origin
.
x
)
/
rightViewContainer
.
frame
.
size
.
width
let
s
:
CGFloat
=
1
-
(
1
-
options
.
contentViewScale
)
*
r
let
m
:
CGFloat
=
rightOrigin
-
rightViewContainer
.
frame
.
size
.
width
let
x
:
CGFloat
=
rightContainer
.
frame
.
origin
.
x
+
gesture
.
translationInView
(
gesture
.
view
!
)
.
x
rightViewContainer
.
frame
.
origin
.
x
=
x
>
rightOrigin
?
rightOrigin
:
x
<
m
?
m
:
x
backdropViewContainer
.
layer
.
opacity
=
Float
(
r
*
options
.
contentViewOpacity
)
mainViewContainer
.
transform
=
CGAffineTransformMakeScale
(
s
,
s
)
if
nil
!=
delegate
?
.
sideNavDidChangeRightPan
{
delegate
?
.
sideNavDidChangeRightPan
?(
self
,
container
:
SideNavContainer
(
state
:
rightContainer
.
state
,
point
:
v
,
frame
:
rightContainer
.
frame
))
}
}
else
{
let
v
:
CGPoint
=
gesture
.
velocityInView
(
gesture
.
view
)
let
x
:
CGFloat
=
v
.
x
<=
-
1000
||
v
.
x
>=
1000
?
v
.
x
:
0
let
s
:
SideNavState
=
rightViewContainer
.
frame
.
origin
.
x
>=
CGFloat
(
floor
(
rightOrigin
)
-
options
.
pointOfNoReturnWidth
)
||
v
.
x
>=
1000
?
.
Closed
:
.
Opened
if
.
Closed
==
s
{
closeRightViewContainer
(
velocity
:
x
)
}
else
{
openRightViewContainer
(
velocity
:
x
)
}
if
nil
!=
delegate
?
.
sideNavDidEndRightPan
{
delegate
?
.
sideNavDidEndRightPan
?(
self
,
container
:
SideNavContainer
(
state
:
s
,
point
:
v
,
frame
:
rightContainer
.
frame
))
}
}
}
//
// :name: handleRightTapGesture
//
internal
func
handleRightTapGesture
(
gesture
:
UIPanGestureRecognizer
)
{
delegate
?
.
sideNavDidTapRight
?(
self
,
container
:
rightContainer
)
closeRightViewContainer
()
}
//
// :name: addShadow
//
private
func
addShadow
(
container
:
UIView
)
{
container
.
layer
.
shadowOffset
=
options
.
shadowOffset
container
.
layer
.
shadowOpacity
=
options
.
shadowOpacity
container
.
layer
.
shadowRadius
=
options
.
shadowRadius
container
.
layer
.
shadowPath
=
UIBezierPath
(
rect
:
container
.
bounds
)
.
CGPath
container
.
layer
.
masksToBounds
=
false
}
//
// :name: removeShadow
//
private
func
removeShadow
(
container
:
UIView
)
{
container
.
layer
.
opacity
=
1
container
.
layer
.
masksToBounds
=
true
}
//
// :name: openWindow
//
private
func
openWindow
()
{
if
options
.
shouldHideStatusBar
{
if
isViewBasedAppearance
{
UIApplication
.
sharedApplication
()
.
setStatusBarHidden
(
true
,
withAnimation
:
.
Slide
)
}
else
{
dispatch_async
(
dispatch_get_main_queue
(),
{
if
let
w
=
UIApplication
.
sharedApplication
()
.
keyWindow
{
w
.
windowLevel
=
UIWindowLevelStatusBar
+
1
}
})
}
}
}
//
// :name: closeWindow
//
private
func
closeWindow
()
{
if
options
.
shouldHideStatusBar
{
if
isViewBasedAppearance
{
UIApplication
.
sharedApplication
()
.
setStatusBarHidden
(
false
,
withAnimation
:
.
Slide
)
}
else
{
dispatch_async
(
dispatch_get_main_queue
(),
{
if
let
w
=
UIApplication
.
sharedApplication
()
.
keyWindow
{
w
.
windowLevel
=
UIWindowLevelNormal
}
})
}
}
}
//
// :name: removeViewController
//
private
func
removeViewController
(
viewController
:
UIViewController
?)
{
if
let
vc
=
viewController
{
vc
.
willMoveToParentViewController
(
nil
)
vc
.
view
.
removeFromSuperview
()
vc
.
removeFromParentViewController
()
}
}
//
// :name: gesturePanLeftViewController
//
private
func
gesturePanLeftViewController
(
gesture
:
UIGestureRecognizer
,
point
:
CGPoint
)
->
Bool
{
return
isLeftContainerOpened
||
options
.
leftPanFromBezel
&&
isLeftPointContainedWithinRect
(
point
)
}
//
// :name: isLeftPointContainedWithinRect
//
private
func
isLeftPointContainedWithinRect
(
point
:
CGPoint
)
->
Bool
{
var
r
:
CGRect
=
CGRectZero
var
t
:
CGRect
=
CGRectZero
let
w
:
CGFloat
=
options
.
leftBezelWidth
CGRectDivide
(
view
.
bounds
,
&
r
,
&
t
,
w
,
.
MinXEdge
)
return
CGRectContainsPoint
(
r
,
point
)
}
//
// :name: gesturePanRightViewController
//
private
func
gesturePanRightViewController
(
gesture
:
UIGestureRecognizer
,
withTouchPoint
point
:
CGPoint
)
->
Bool
{
return
isRightContainerOpened
||
options
.
rightPanFromBezel
&&
isRightPointContainedWithinRect
(
point
)
}
//
// :name: isRightPointContainedWithinRect
//
private
func
isRightPointContainedWithinRect
(
point
:
CGPoint
)
->
Bool
{
var
r
:
CGRect
=
CGRectZero
var
t
:
CGRect
=
CGRectZero
let
w
:
CGFloat
=
rightOrigin
-
options
.
rightBezelWidth
CGRectDivide
(
view
.
bounds
,
&
t
,
&
r
,
w
,
.
MinXEdge
)
return
CGRectContainsPoint
(
r
,
point
)
}
//
// :name: isPointContainedWithinLeftRectViewController
//
private
func
isPointContainedWithinLeftRectViewController
(
point
:
CGPoint
)
->
Bool
{
return
CGRectContainsPoint
(
leftViewContainer
.
frame
,
point
)
}
//
// :name: isPointContainedWithinRightViewController
//
private
func
isPointContainedWithinRightViewController
(
point
:
CGPoint
)
->
Bool
{
return
CGRectContainsPoint
(
rightViewContainer
.
frame
,
point
)
}
//
// :name: prepareMainContainer
//
private
func
prepareMainContainer
()
{
mainViewContainer
=
UIView
(
frame
:
view
.
bounds
)
mainViewContainer
.
backgroundColor
=
.
clearColor
()
mainViewContainer
.
autoresizingMask
=
.
FlexibleHeight
|
.
FlexibleWidth
view
.
addSubview
(
mainViewContainer
)
}
//
// :name: prepareBackdropContainer
//
private
func
prepareBackdropContainer
()
{
backdropViewContainer
=
UIView
(
frame
:
view
.
bounds
)
backdropViewContainer
.
backgroundColor
=
options
.
backdropViewContainerBackgroundColor
backdropViewContainer
.
autoresizingMask
=
.
FlexibleHeight
|
.
FlexibleWidth
backdropViewContainer
.
layer
.
opacity
=
0
view
.
addSubview
(
backdropViewContainer
)
}
//
// :name: prepareLeftContainer
//
private
func
prepareLeftContainer
()
{
leftContainer
=
SideNavContainer
(
state
:
.
Closed
,
point
:
CGPointZero
,
frame
:
CGRectZero
)
var
b
:
CGRect
=
view
.
bounds
b
.
size
.
width
=
options
.
leftViewContainerWidth
b
.
origin
.
x
=
leftOrigin
leftViewContainer
=
UIView
(
frame
:
b
)
leftViewContainer
.
backgroundColor
=
.
clearColor
()
leftViewContainer
.
autoresizingMask
=
.
FlexibleHeight
view
.
addSubview
(
leftViewContainer
)
}
//
// :name: prepareLeftContainerToOpen
//
private
func
prepareLeftContainerToOpen
()
{
leftViewController
?
.
beginAppearanceTransition
(
!
isLeftContainerOpened
,
animated
:
true
)
addShadow
(
leftViewContainer
)
openWindow
()
}
//
// :name: prepareLeftContainerToClose
//
private
func
prepareLeftContainerToClose
()
{
leftViewController
?
.
beginAppearanceTransition
(
isLeftContainerOpened
,
animated
:
true
)
closeWindow
()
}
//
// :name: prepareLeftGestures
//
private
func
prepareLeftGestures
()
{
removeLeftGestures
()
addLeftGestures
()
}
//
// :name: prepareRightContainer
//
private
func
prepareRightContainer
()
{
rightContainer
=
SideNavContainer
(
state
:
.
Closed
,
point
:
CGPointZero
,
frame
:
CGRectZero
)
var
b
:
CGRect
=
view
.
bounds
b
.
size
.
width
=
options
.
rightViewContainerWidth
b
.
origin
.
x
=
rightOrigin
rightViewContainer
=
UIView
(
frame
:
b
)
rightViewContainer
.
backgroundColor
=
.
clearColor
()
rightViewContainer
.
autoresizingMask
=
.
FlexibleHeight
view
.
addSubview
(
rightViewContainer
)
}
//
// :name: prepareRightContainerToOpen
//
private
func
prepareRightContainerToOpen
()
{
rightViewController
?
.
beginAppearanceTransition
(
!
isRightContainerOpened
,
animated
:
true
)
addShadow
(
rightViewContainer
)
openWindow
()
}
//
// :name: prepareRightContainerToClose
//
private
func
prepareRightContainerToClose
()
{
rightViewController
?
.
beginAppearanceTransition
(
isRightContainerOpened
,
animated
:
true
)
closeWindow
()
}
//
// :name: prepareRightGestures
//
private
func
prepareRightGestures
()
{
removeRightGestures
()
addRightGestures
()
}
//
// :name: prepareContainedViewController
//
private
func
prepareContainedViewController
(
container
:
UIView
,
viewController
:
UIViewController
?)
{
if
let
vc
=
viewController
{
addChildViewController
(
vc
)
vc
.
view
.
frame
=
container
.
bounds
container
.
addSubview
(
vc
.
view
)
vc
.
didMoveToParentViewController
(
self
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment