Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82f99a2cba | |||
| 1a1123967d | |||
| f945155814 | |||
| 10345d4776 | |||
| a49883580d | |||
| a94dd58950 | |||
| e360068f68 | |||
| a4aac9536a | |||
| fb20329cb1 | |||
| d62695ae2d | |||
| 8d78be525e | |||
| 7e4b8365ee | |||
| 1d32cd1b7b | |||
| f2299bb5e4 | |||
| 5aac1f26e8 | |||
| ef1d05607f | |||
| aca41e0ed3 | |||
| 4b07c5ffe5 | |||
| 8305c2f13d | |||
| 3631570657 | |||
| 74ccc791f8 | |||
| 374818587a |
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- SideMenu (0.1.0)
|
||||
- SideMenu (0.1.6)
|
||||
|
||||
DEPENDENCIES:
|
||||
- SideMenu (from `../`)
|
||||
@@ -9,6 +9,6 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
SideMenu: 62c97561370244e645f3bccecb8a9055f78d0ccc
|
||||
SideMenu: 102bdf48ac5228b1a4a68bdd0b10232adbdbfdb0
|
||||
|
||||
COCOAPODS: 0.39.0
|
||||
|
||||
+5
-4
@@ -1,16 +1,17 @@
|
||||
{
|
||||
"name": "SideMenu",
|
||||
"version": "0.1.0",
|
||||
"summary": "SideMenu is a simple and versatile side menu control.",
|
||||
"description": "SideMenu is a simple and versatile side menu control. It's highly customizable, but can also be implemented in storyboard without a single line of code. The are three standard animation styles to choose from along with several other options for further customization if desired.",
|
||||
"version": "0.1.6",
|
||||
"summary": "Simple side menu control in Swift inspired by Facebook. Right and Left sides. No coding required.",
|
||||
"description": "SideMenu is a simple and versatile side menu control. It's highly customizable, but can also be implemented in storyboard without a single line of code. The are three standard animation styles to choose from along with several other options for further customization if desired. Just type SideMenuManager.menu... and code completion will show you everything you can customize.",
|
||||
"homepage": "https://github.com/jonkykong/SideMenu",
|
||||
"screenshots": "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Preview.gif",
|
||||
"license": "MIT",
|
||||
"authors": {
|
||||
"jonkykong": "jonk@jonked.com"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/jonkykong/SideMenu.git",
|
||||
"tag": "0.1.0"
|
||||
"tag": "0.1.6"
|
||||
},
|
||||
"platforms": {
|
||||
"ios": "8.0"
|
||||
|
||||
Generated
+2
-2
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- SideMenu (0.1.0)
|
||||
- SideMenu (0.1.6)
|
||||
|
||||
DEPENDENCIES:
|
||||
- SideMenu (from `../`)
|
||||
@@ -9,6 +9,6 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
SideMenu: 62c97561370244e645f3bccecb8a9055f78d0ccc
|
||||
SideMenu: 102bdf48ac5228b1a4a68bdd0b10232adbdbfdb0
|
||||
|
||||
COCOAPODS: 0.39.0
|
||||
|
||||
+38
-19
@@ -7,13 +7,16 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
136BF9383BF2527B070BA5717DBA9D7F /* SideMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA288F42456ACA5ACB2CF80A5ADB09A /* SideMenuManager.swift */; };
|
||||
3876451029D26E27CF659DA08BDBA909 /* UISideMenuNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE16A7DD7BD7A0F908B6D5D9660270A9 /* UISideMenuNavigationController.swift */; };
|
||||
38E7197A7FA54FE6EA9474F7C71E9F16 /* SideMenu.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 80BEBB037771664BE7EDD19D9FA27CF9 /* SideMenu.bundle */; };
|
||||
654B24B050E549972B44628F3D457134 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; };
|
||||
65CAFD32BFFE0B95AC0AD095EE320645 /* SideMenu-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 065251241095423AD65BFAC01FD1EFC6 /* SideMenu-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
6B68286B3E7B0CB2FE5C392902281CE1 /* SideMenu-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B967E268029BFFB818450080E0070B3 /* SideMenu-dummy.m */; };
|
||||
8AA9CBD72AFC76A9039A8CF9CE6AC1B1 /* Pods-SideMenu_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BE2CB4DECBCC7820640717CC54B8B6 /* Pods-SideMenu_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8AFB3DFF4F1A5C3F872B5980F29340A0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; };
|
||||
92A9FE9F77CE2BA2AB924DB02E446C76 /* SideMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B5455C690C42784185F70B2287AEA03 /* SideMenuManager.swift */; };
|
||||
BBA8C724C31EBC571ED008721DC191C7 /* SideMenu-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B967E268029BFFB818450080E0070B3 /* SideMenu-dummy.m */; };
|
||||
92E1730BB52E7F211ABDEA6120B3CBC0 /* UITableViewVibrantCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F27B28C13E47CE793DCD786ABE0EBA0 /* UITableViewVibrantCell.swift */; };
|
||||
B7BAC40F47999790437216BD070E4B0B /* SideMenuTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89C2BD310402418B97E451D4C32129D /* SideMenuTransition.swift */; };
|
||||
D15E623D3EA1175C6ECE8E7F96F03F1B /* Pods-SideMenu_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F3BE17EC6C115709ADE0336BED36620B /* Pods-SideMenu_Example-dummy.m */; };
|
||||
E8F227DB44F0E28D22866613E7466FE8 /* Pods-SideMenu_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6442E0432AE7807F49351AA4A2662BA0 /* Pods-SideMenu_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
E93EFE2668CC8435D5DE5C232FA073A2 /* Pods-SideMenu_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8894543047CFB1B0AD661193D079E3AF /* Pods-SideMenu_Tests-dummy.m */; };
|
||||
@@ -49,12 +52,12 @@
|
||||
02386539B907565FEF643C0A13DFD87A /* Pods-SideMenu_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SideMenu_Example-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
065251241095423AD65BFAC01FD1EFC6 /* SideMenu-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SideMenu-umbrella.h"; sourceTree = "<group>"; };
|
||||
080DBC3EDE1B586D2C363264990812F4 /* Pods_SideMenu_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SideMenu_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0B5455C690C42784185F70B2287AEA03 /* SideMenuManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SideMenuManager.swift; sourceTree = "<group>"; };
|
||||
167CC8746E153424CD7BBFBEB1FCC761 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
18CAD0A610A9A596A337B81EA6C75E82 /* SideMenu.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SideMenu.xcconfig; sourceTree = "<group>"; };
|
||||
1B967E268029BFFB818450080E0070B3 /* SideMenu-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SideMenu-dummy.m"; sourceTree = "<group>"; };
|
||||
27F802E03D96716FDA4B8EB2F79D3442 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
283B837F6AEE40BE625A3B7BF3D629C4 /* Pods-SideMenu_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SideMenu_Tests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2F27B28C13E47CE793DCD786ABE0EBA0 /* UITableViewVibrantCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UITableViewVibrantCell.swift; sourceTree = "<group>"; };
|
||||
365023FDA9AABF541F5F2BB4897DBC3D /* SideMenu-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SideMenu-prefix.pch"; sourceTree = "<group>"; };
|
||||
3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
43082750426B0601530DDE0E513C028D /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@@ -71,9 +74,12 @@
|
||||
9BD9EE073A93C4FF5537C83246116880 /* Pods_SideMenu_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SideMenu_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9EF8186F4C9E56B047D9FD1A6E197E35 /* Pods-SideMenu_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SideMenu_Tests-resources.sh"; sourceTree = "<group>"; };
|
||||
A108300E5F9E66CC5B80C6D158F1A2B4 /* Pods-SideMenu_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SideMenu_Tests-frameworks.sh"; sourceTree = "<group>"; };
|
||||
B89C2BD310402418B97E451D4C32129D /* SideMenuTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SideMenuTransition.swift; sourceTree = "<group>"; };
|
||||
BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
CCFF9BC0A5E0AEB1B572E08B7BEB5179 /* Pods-SideMenu_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SideMenu_Example.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
CE16A7DD7BD7A0F908B6D5D9660270A9 /* UISideMenuNavigationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UISideMenuNavigationController.swift; sourceTree = "<group>"; };
|
||||
DB5D86340A731D1EBAB66BA453409E3B /* Pods-SideMenu_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SideMenu_Tests-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
DBA288F42456ACA5ACB2CF80A5ADB09A /* SideMenuManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SideMenuManager.swift; sourceTree = "<group>"; };
|
||||
DDF7D1E1EB67D0EE22B89DBA15B34455 /* Pods-SideMenu_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SideMenu_Tests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
DE75E648D267654445B52C8280543EFD /* Pods-SideMenu_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SideMenu_Tests-acknowledgements.markdown"; sourceTree = "<group>"; };
|
||||
F3BE17EC6C115709ADE0336BED36620B /* Pods-SideMenu_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SideMenu_Example-dummy.m"; sourceTree = "<group>"; };
|
||||
@@ -126,17 +132,20 @@
|
||||
34BEDB4240BF71B8086595F752B69042 /* SideMenu */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CB203E0872A2E52C8E99D04334ED5A9D /* Pod */,
|
||||
A332AD7F12D36E82A15A055F8C320B9B /* Pod */,
|
||||
E193E81FDAC4759729D7C787A23DAA84 /* Support Files */,
|
||||
);
|
||||
name = SideMenu;
|
||||
path = ../..;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
42F4169C1135EF13A1D0421D270BD2F4 /* Classes */ = {
|
||||
46BA4BFCFF15B4CAA79C17449E551388 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0B5455C690C42784185F70B2287AEA03 /* SideMenuManager.swift */,
|
||||
DBA288F42456ACA5ACB2CF80A5ADB09A /* SideMenuManager.swift */,
|
||||
B89C2BD310402418B97E451D4C32129D /* SideMenuTransition.swift */,
|
||||
CE16A7DD7BD7A0F908B6D5D9660270A9 /* UISideMenuNavigationController.swift */,
|
||||
2F27B28C13E47CE793DCD786ABE0EBA0 /* UITableViewVibrantCell.swift */,
|
||||
);
|
||||
path = Classes;
|
||||
sourceTree = "<group>";
|
||||
@@ -190,6 +199,14 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A332AD7F12D36E82A15A055F8C320B9B /* Pod */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
46BA4BFCFF15B4CAA79C17449E551388 /* Classes */,
|
||||
);
|
||||
path = Pod;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A94B9130D4AB3D2F2C9607150B2ADFB6 /* Pods-SideMenu_Example */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -224,14 +241,6 @@
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CB203E0872A2E52C8E99D04334ED5A9D /* Pod */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
42F4169C1135EF13A1D0421D270BD2F4 /* Classes */,
|
||||
);
|
||||
path = Pod;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E193E81FDAC4759729D7C787A23DAA84 /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -298,7 +307,7 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9057029D293AD6EDC6335C1F302EE42B /* Build configuration list for PBXNativeTarget "SideMenu" */;
|
||||
buildPhases = (
|
||||
CA771114E7DB1C9C7E995AE8242C4F19 /* Sources */,
|
||||
CE5E64CE3BE1AEA0E67C995DC80DB5F0 /* Sources */,
|
||||
CD3D74524BB0D7B632CB6C81160DEEE1 /* Frameworks */,
|
||||
FAC25EAFE8B8901BDEDD21DAC9DD45ED /* Resources */,
|
||||
39BFA88BB58C8DFDF21395C7A6FD7D25 /* Headers */,
|
||||
@@ -355,7 +364,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0700;
|
||||
LastUpgradeCheck = 0720;
|
||||
};
|
||||
buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@@ -419,12 +428,15 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
CA771114E7DB1C9C7E995AE8242C4F19 /* Sources */ = {
|
||||
CE5E64CE3BE1AEA0E67C995DC80DB5F0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BBA8C724C31EBC571ED008721DC191C7 /* SideMenu-dummy.m in Sources */,
|
||||
92A9FE9F77CE2BA2AB924DB02E446C76 /* SideMenuManager.swift in Sources */,
|
||||
6B68286B3E7B0CB2FE5C392902281CE1 /* SideMenu-dummy.m in Sources */,
|
||||
136BF9383BF2527B070BA5717DBA9D7F /* SideMenuManager.swift in Sources */,
|
||||
B7BAC40F47999790437216BD070E4B0B /* SideMenuTransition.swift in Sources */,
|
||||
3876451029D26E27CF659DA08BDBA909 /* UISideMenuNavigationController.swift in Sources */,
|
||||
92E1730BB52E7F211ABDEA6120B3CBC0 /* UITableViewVibrantCell.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -485,6 +497,7 @@
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = Pods_SideMenu_Example;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -516,6 +529,7 @@
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = Pods_SideMenu_Tests;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -546,6 +560,7 @@
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = Pods_SideMenu_Example;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -573,6 +588,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@@ -624,6 +640,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/SideMenu/SideMenu.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = SideMenu;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -654,6 +671,7 @@
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = Pods_SideMenu_Tests;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -682,6 +700,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/SideMenu/SideMenu.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = SideMenu;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
|
||||
@@ -1,36 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0720"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForAnalyzing = "YES"
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES">
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = 'primary'
|
||||
BlueprintIdentifier = '6D5700AB4DD41D539909DBA7'
|
||||
BlueprintName = 'SideMenu'
|
||||
ReferencedContainer = 'container:Pods.xcodeproj'
|
||||
BuildableName = 'SideMenu.framework'>
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "92B1C7A9E8122442B031A44C1CA691AF"
|
||||
BuildableName = "SideMenu.framework"
|
||||
BlueprintName = "SideMenu"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
@@ -38,17 +41,25 @@
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
buildConfiguration = "Debug"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "92B1C7A9E8122442B031A44C1CA691AF"
|
||||
BuildableName = "SideMenu.framework"
|
||||
BlueprintName = "SideMenu"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
|
||||
+20
-20
@@ -2,25 +2,25 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
+20
-20
@@ -2,25 +2,25 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
+20
-20
@@ -2,25 +2,25 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1.6</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="yAA-s6-Bam">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
@@ -92,7 +93,7 @@
|
||||
<action selector="changeSegment:" destination="QHN-nZ-kbB" eventType="valueChanged" id="5cv-dF-wWs"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.01" minValue="0.001" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="Xp9-C5-Td1">
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.001" minValue="0.001" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="Xp9-C5-Td1">
|
||||
<rect key="frame" x="18" y="368" width="284" height="31"/>
|
||||
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<connections>
|
||||
@@ -218,7 +219,7 @@
|
||||
<barButtonItem key="backBarButtonItem" title=" " id="FVG-mn-9HX"/>
|
||||
<barButtonItem key="leftBarButtonItem" title="Left Menu" id="hjJ-My-xDQ">
|
||||
<connections>
|
||||
<segue destination="DuX-EW-0mP" kind="presentation" id="yoa-B2-xG5"/>
|
||||
<segue destination="DuX-EW-0mP" kind="presentation" identifier="Test" id="yoa-B2-xG5"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" title="Right Menu" id="ckn-oO-hhX">
|
||||
@@ -242,15 +243,18 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="142" y="336"/>
|
||||
</scene>
|
||||
<!--Left Menu Navigation Controller-->
|
||||
<!--Side Menu Navigation Controller-->
|
||||
<scene sceneID="Zbc-0f-8nT">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="UILeftMenuNavigationController" navigationBarHidden="YES" id="DuX-EW-0mP" customClass="UILeftMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
|
||||
<navigationController storyboardIdentifier="LeftMenuNavigationController" navigationBarHidden="YES" id="DuX-EW-0mP" customClass="UISideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
|
||||
<navigationItem key="navigationItem" id="ipz-Lx-Wgf"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="35F-wh-r6h">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="leftSide" value="YES"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<segue destination="V6g-oO-Tbm" kind="relationship" relationship="rootViewController" id="Zvt-Bp-XoT"/>
|
||||
</connections>
|
||||
@@ -266,7 +270,7 @@
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" scrollEnabled="NO" dataMode="static" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="Dqh-bs-m2M">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.25134698280000001" colorSpace="calibratedWhite"/>
|
||||
<color key="tintColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<inset key="separatorInset" minX="15" minY="0.0" maxX="8" maxY="0.0"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="vVB-ag-TnU">
|
||||
@@ -375,10 +379,10 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3896.25" y="0.0"/>
|
||||
</scene>
|
||||
<!--Right Menu Navigation Controller-->
|
||||
<!--Side Menu Navigation Controller-->
|
||||
<scene sceneID="kei-0w-mFw">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="UIRightMenuNavigationController" navigationBarHidden="YES" id="z7k-fk-pfc" customClass="UIRightMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
|
||||
<navigationController storyboardIdentifier="RightMenuNavigationController" navigationBarHidden="YES" id="z7k-fk-pfc" customClass="UISideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="qOd-yQ-2i8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
@@ -398,7 +402,7 @@
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" scrollEnabled="NO" dataMode="static" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="49z-eA-JB7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.25134698275862066" colorSpace="calibratedWhite"/>
|
||||
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="15" maxY="0.0"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="UXT-t2-k90">
|
||||
<rect key="frame" x="0.0" y="132" width="320" height="0.0"/>
|
||||
|
||||
@@ -26,9 +26,9 @@ class MainViewController: UIViewController {
|
||||
|
||||
private func setupSideMenu() {
|
||||
// Define the menus
|
||||
SideMenuManager.menuLeftNavigationController = storyboard!.instantiateViewControllerWithIdentifier("UILeftMenuNavigationController") as? UILeftMenuNavigationController
|
||||
SideMenuManager.menuRightNavigationController = storyboard!.instantiateViewControllerWithIdentifier("UIRightMenuNavigationController") as? UIRightMenuNavigationController
|
||||
|
||||
SideMenuManager.menuLeftNavigationController = storyboard!.instantiateViewControllerWithIdentifier("LeftMenuNavigationController") as? UISideMenuNavigationController
|
||||
SideMenuManager.menuRightNavigationController = storyboard!.instantiateViewControllerWithIdentifier("RightMenuNavigationController") as? UISideMenuNavigationController
|
||||
|
||||
// Enable gestures. The left and/or right menus must be set up above for these to work.
|
||||
// Note that these continue to work on the Navigation Controller independent of the View Controller it displays!
|
||||
SideMenuManager.menuAddPanGestureToPresent(toView: self.navigationController!.navigationBar)
|
||||
@@ -57,7 +57,6 @@ class MainViewController: UIViewController {
|
||||
}
|
||||
|
||||
@IBAction private func changeSegment(segmentControl: UISegmentedControl) {
|
||||
presentViewController(SideMenuManager.menuLeftNavigationController!, animated: true, completion: nil)
|
||||
switch segmentControl {
|
||||
case presentModeSegmentedControl:
|
||||
let modes:[SideMenuManager.MenuPresentMode] = [.MenuSlideIn, .ViewSlideOut, .MenuDissolveIn]
|
||||
|
||||
@@ -6,188 +6,24 @@
|
||||
//
|
||||
|
||||
/* Example usage:
|
||||
SideMenuManager.menuLeftNavigationController = storyboard!.instantiateViewControllerWithIdentifier("UILeftMenuNavigationController") as? UILeftMenuNavigationController
|
||||
SideMenuManager.menuRightNavigationController = storyboard!.instantiateViewControllerWithIdentifier("UIRightMenuNavigationController") as? UIRightMenuNavigationController
|
||||
SideMenuManager.menuAddPanToPresentGesture(toView: self.navigationController!.navigationBar)
|
||||
// Define the menus
|
||||
SideMenuManager.menuLeftNavigationController = storyboard!.instantiateViewControllerWithIdentifier("LeftMenuNavigationController") as? UISideMenuNavigationController
|
||||
SideMenuManager.menuRightNavigationController = storyboard!.instantiateViewControllerWithIdentifier("RightMenuNavigationController") as? UISideMenuNavigationController
|
||||
|
||||
// Enable gestures. The left and/or right menus must be set up above for these to work.
|
||||
// Note that these continue to work on the Navigation Controller independent of the View Controller it displays!
|
||||
SideMenuManager.menuAddPanGestureToPresent(toView: self.navigationController!.navigationBar)
|
||||
SideMenuManager.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController!.view)
|
||||
*/
|
||||
|
||||
private func menuViewDidAppear(navigationController: UINavigationController) {
|
||||
// we had presented a view before, so lets dismiss ourselves as already acted upon
|
||||
if navigationController.view.hidden {
|
||||
SideMenuManager.hideMenuComplete()
|
||||
navigationController.dismissViewControllerAnimated(false, completion: { () -> Void in
|
||||
navigationController.view.hidden = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func menuViewWillDisappear(navigationController: UINavigationController) {
|
||||
// when presenting a view controller from the menu, the menu view gets moved into another transition view above our transition container
|
||||
// which can break the visual layout we had before. So, we move the menu view back to its original transition view to preserve it.
|
||||
if !navigationController.isBeingDismissed() {
|
||||
if let mainView = navigationController.presentingViewController?.view {
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
mainView.superview?.insertSubview(navigationController.view, belowSubview: mainView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
mainView.superview?.insertSubview(navigationController.view, aboveSubview: SideMenuManager.tapView)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func menuViewDidDisappear(navigationController: UINavigationController) {
|
||||
// we're presenting a view controller from the menu, so we need to hide the menu so it isn't g when the presented view is dismissed.
|
||||
if !navigationController.isBeingDismissed() {
|
||||
navigationController.view.hidden = true
|
||||
SideMenuManager.hideMenuAppearance()
|
||||
}
|
||||
}
|
||||
|
||||
private func menuViewWillTransitionToSize(navigationController: UINavigationController, size: CGSize, coordinator: UIViewControllerTransitionCoordinator) {
|
||||
// don't bother resizing if the view isn't visible
|
||||
if navigationController.view.hidden {
|
||||
return
|
||||
}
|
||||
|
||||
SideMenuManager.statusBarView?.hidden = true
|
||||
coordinator.animateAlongsideTransition({ (context) -> Void in
|
||||
SideMenuManager.presentMenuAppearance(forSize: size)
|
||||
}) { (context) -> Void in
|
||||
SideMenuManager.statusBarView?.hidden = false
|
||||
}
|
||||
}
|
||||
|
||||
private func menuPushViewController(navigationController: UINavigationController, viewController: UIViewController, animated: Bool) {
|
||||
if let menuViewController: UINavigationController = SideMenuManager.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
|
||||
if let presentingViewController = menuViewController.presentingViewController as? UINavigationController {
|
||||
|
||||
// to avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
|
||||
// is dismissed after showing the appropriate screen
|
||||
CATransaction.begin()
|
||||
CATransaction.setCompletionBlock( { () -> Void in
|
||||
navigationController.dismissViewControllerAnimated(true, completion: nil)
|
||||
navigationController.visibleViewController?.viewWillAppear(false) // Hack: force selection to get cleared on UITableViewControllers when reappearing using custom transitions
|
||||
})
|
||||
|
||||
UIView.animateWithDuration(SideMenuManager.menuAnimationDismissDuration, animations: { () -> Void in
|
||||
SideMenuManager.hideMenuAppearance()
|
||||
})
|
||||
|
||||
if SideMenuManager.menuAllowPopIfPossible {
|
||||
for subViewController in presentingViewController.viewControllers {
|
||||
if subViewController.dynamicType == viewController.dynamicType {
|
||||
presentingViewController.popToViewController(subViewController, animated: animated)
|
||||
CATransaction.commit()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if !SideMenuManager.menuAllowPushOfSameClassTwice {
|
||||
if presentingViewController.viewControllers.last?.dynamicType == viewController.dynamicType {
|
||||
CATransaction.commit()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
presentingViewController.pushViewController(viewController, animated: animated)
|
||||
CATransaction.commit()
|
||||
} else {
|
||||
menuViewController.presentViewController(viewController, animated: animated, completion: nil)
|
||||
print("Warning: attempted to push a ViewController from a ViewController that doesn't have a NavigationController. It will be presented it instead.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UILeftMenuNavigationController: UINavigationController {
|
||||
|
||||
override public func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
SideMenuManager.menuLeftNavigationController = self
|
||||
}
|
||||
|
||||
override public func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
menuViewDidAppear(self)
|
||||
}
|
||||
|
||||
override public func viewWillDisappear(animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
menuViewWillDisappear(self)
|
||||
}
|
||||
|
||||
override public func viewDidDisappear(animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
|
||||
menuViewDidDisappear(self)
|
||||
}
|
||||
|
||||
override public func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
|
||||
|
||||
menuViewWillTransitionToSize(self, size: size, coordinator: coordinator)
|
||||
}
|
||||
|
||||
override public func pushViewController(viewController: UIViewController, animated: Bool) {
|
||||
menuPushViewController(self, viewController: viewController, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
public class UIRightMenuNavigationController: UINavigationController {
|
||||
|
||||
override public func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
SideMenuManager.menuRightNavigationController = self
|
||||
}
|
||||
|
||||
override public func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
menuViewDidAppear(self)
|
||||
}
|
||||
|
||||
override public func viewWillDisappear(animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
menuViewWillDisappear(self)
|
||||
}
|
||||
|
||||
override public func viewDidDisappear(animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
|
||||
menuViewDidDisappear(self)
|
||||
}
|
||||
|
||||
override public func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
|
||||
|
||||
menuViewWillTransitionToSize(self, size: size, coordinator: coordinator)
|
||||
}
|
||||
|
||||
override public func pushViewController(viewController: UIViewController, animated: Bool) {
|
||||
menuPushViewController(self, viewController: viewController, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
|
||||
public class SideMenuManager {
|
||||
|
||||
public enum MenuPresentMode {
|
||||
case MenuSlideIn
|
||||
case ViewSlideOut
|
||||
case MenuDissolveIn
|
||||
}
|
||||
|
||||
private static var presenting = false
|
||||
private static var interactive = false
|
||||
private static var presentDirection: UIRectEdge = .Left;
|
||||
private static weak var tapView: UIView!
|
||||
private static weak var statusBarView: UIView?
|
||||
private static let singleton = SideMenuManager()
|
||||
|
||||
private static var originalLeftMenuBackgroundColor: UIColor?
|
||||
private static var originalRightMenuBackgroundColor: UIColor?
|
||||
|
||||
@@ -215,10 +51,7 @@ public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewContro
|
||||
}
|
||||
}
|
||||
|
||||
// prevent instantiation
|
||||
private override init() {}
|
||||
|
||||
public static var menuLeftNavigationController: UILeftMenuNavigationController? {
|
||||
public static var menuLeftNavigationController: UISideMenuNavigationController? {
|
||||
willSet {
|
||||
if menuLeftNavigationController != nil {
|
||||
let originalBlurEffectStyle = menuBlurEffectStyle
|
||||
@@ -230,16 +63,17 @@ public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewContro
|
||||
didSet {
|
||||
if let menuLeftNavigationController = menuLeftNavigationController {
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(self, action:"handleHideMenuPan:")
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:"handleHideMenuPan:")
|
||||
menuLeftNavigationController.view.addGestureRecognizer(exitPanGesture)
|
||||
menuLeftNavigationController.transitioningDelegate = singleton
|
||||
menuLeftNavigationController.transitioningDelegate = SideMenuTransition.singleton
|
||||
menuLeftNavigationController.modalPresentationStyle = .OverFullScreen
|
||||
menuLeftSwipeToDismissGesture = exitPanGesture
|
||||
updateMenuBlurIfNecessary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static var menuRightNavigationController: UIRightMenuNavigationController? {
|
||||
public static var menuRightNavigationController: UISideMenuNavigationController? {
|
||||
willSet {
|
||||
if menuRightNavigationController != nil {
|
||||
let originalBlurEffectStyle = menuBlurEffectStyle
|
||||
@@ -251,9 +85,10 @@ public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewContro
|
||||
didSet {
|
||||
if let menuRightNavigationController = menuRightNavigationController {
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(self, action:"handleHideMenuPan:")
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:"handleHideMenuPan:")
|
||||
menuRightNavigationController.view.addGestureRecognizer(exitPanGesture)
|
||||
menuRightNavigationController.transitioningDelegate = singleton
|
||||
menuRightNavigationController.transitioningDelegate = SideMenuTransition.singleton
|
||||
menuRightNavigationController.modalPresentationStyle = .OverFullScreen
|
||||
menuRightSwipeToDismissGesture = exitPanGesture
|
||||
updateMenuBlurIfNecessary()
|
||||
}
|
||||
@@ -320,19 +155,13 @@ public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewContro
|
||||
}
|
||||
}
|
||||
|
||||
private static var viewControllerForPresentedMenu: UIViewController? {
|
||||
get {
|
||||
return menuLeftNavigationController?.presentingViewController != nil ? menuLeftNavigationController?.presentingViewController : menuRightNavigationController?.presentingViewController
|
||||
}
|
||||
}
|
||||
|
||||
public class func menuAddScreenEdgePanGesturesToPresent(toView toView: UIView, forMenu:UIRectEdge? = nil) -> [UIScreenEdgePanGestureRecognizer] {
|
||||
|
||||
var array = [UIScreenEdgePanGestureRecognizer]()
|
||||
|
||||
if forMenu != .Right {
|
||||
let leftScreenEdgeGestureRecognizer = UIScreenEdgePanGestureRecognizer()
|
||||
leftScreenEdgeGestureRecognizer.addTarget(self, action:"handlePresentMenuPan:")
|
||||
leftScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:"handlePresentMenuPan:")
|
||||
leftScreenEdgeGestureRecognizer.edges = .Left
|
||||
leftScreenEdgeGestureRecognizer.cancelsTouchesInView = true
|
||||
toView.addGestureRecognizer(leftScreenEdgeGestureRecognizer)
|
||||
@@ -341,7 +170,7 @@ public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewContro
|
||||
|
||||
if forMenu != .Left {
|
||||
let rightScreenEdgeGestureRecognizer = UIScreenEdgePanGestureRecognizer()
|
||||
rightScreenEdgeGestureRecognizer.addTarget(self, action:"handlePresentMenuPan:")
|
||||
rightScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:"handlePresentMenuPan:")
|
||||
rightScreenEdgeGestureRecognizer.edges = .Right
|
||||
rightScreenEdgeGestureRecognizer.cancelsTouchesInView = true
|
||||
toView.addGestureRecognizer(rightScreenEdgeGestureRecognizer)
|
||||
@@ -353,404 +182,9 @@ public class SideMenuManager: UIPercentDrivenInteractiveTransition, UIViewContro
|
||||
|
||||
public class func menuAddPanGestureToPresent(toView toView: UIView) -> UIPanGestureRecognizer {
|
||||
let panGestureRecognizer = UIPanGestureRecognizer()
|
||||
panGestureRecognizer.addTarget(self, action:"handlePresentMenuPan:")
|
||||
panGestureRecognizer.addTarget(SideMenuTransition.self, action:"handlePresentMenuPan:")
|
||||
toView.addGestureRecognizer(panGestureRecognizer)
|
||||
|
||||
return panGestureRecognizer
|
||||
}
|
||||
|
||||
class func handlePresentMenuPan(pan: UIPanGestureRecognizer) {
|
||||
// how much distance have we panned in reference to the parent view?
|
||||
if let view = viewControllerForPresentedMenu != nil ? viewControllerForPresentedMenu?.view : pan.view {
|
||||
let transform = view.transform
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let translation = pan.translationInView(pan.view!)
|
||||
view.transform = transform
|
||||
|
||||
// do some math to translate this to a percentage based value
|
||||
if !interactive {
|
||||
if translation.x == 0 {
|
||||
return // not sure which way the user is swiping yet, so do nothing
|
||||
}
|
||||
|
||||
if let edge = pan as? UIScreenEdgePanGestureRecognizer {
|
||||
presentDirection = edge.edges == .Left ? .Left : .Right
|
||||
} else {
|
||||
presentDirection = translation.x > 0 ? .Left : .Right
|
||||
}
|
||||
|
||||
if let menuViewController: UINavigationController = presentDirection == .Left ? menuLeftNavigationController : menuRightNavigationController {
|
||||
interactive = true
|
||||
if let visibleViewController = visibleViewController() {
|
||||
visibleViewController.presentViewController(menuViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let direction:CGFloat = presentDirection == .Left ? 1 : -1
|
||||
let distance = translation.x / menuWidth
|
||||
// now lets deal with different states that the gesture recognizer sends
|
||||
switch (pan.state) {
|
||||
case .Began, .Changed:
|
||||
if pan is UIScreenEdgePanGestureRecognizer {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
} else if distance > 0 && presentDirection == .Right && menuLeftNavigationController != nil {
|
||||
presentDirection = .Left
|
||||
singleton.cancelInteractiveTransition()
|
||||
viewControllerForPresentedMenu?.presentViewController(menuLeftNavigationController!, animated: true, completion: nil)
|
||||
} else if distance < 0 && presentDirection == .Left && menuRightNavigationController != nil {
|
||||
presentDirection = .Right
|
||||
singleton.cancelInteractiveTransition()
|
||||
viewControllerForPresentedMenu?.presentViewController(menuRightNavigationController!, animated: true, completion: nil)
|
||||
} else {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
}
|
||||
default:
|
||||
interactive = false
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
view.transform = transform
|
||||
if velocity >= 100 || velocity >= -50 && abs(distance) >= 0.5 {
|
||||
singleton.finishInteractiveTransition()
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class func handleHideMenuPan(pan: UIPanGestureRecognizer) {
|
||||
|
||||
let translation = pan.translationInView(pan.view!)
|
||||
let direction:CGFloat = presentDirection == .Left ? -1 : 1
|
||||
let distance = translation.x / menuWidth * direction
|
||||
|
||||
switch (pan.state) {
|
||||
|
||||
case .Began:
|
||||
interactive = true
|
||||
viewControllerForPresentedMenu?.dismissViewControllerAnimated(true, completion: nil)
|
||||
case .Changed:
|
||||
singleton.updateInteractiveTransition(max(min(distance, 1), 0))
|
||||
default:
|
||||
interactive = false
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
if velocity >= 100 || velocity >= -50 && distance >= 0.5 {
|
||||
singleton.finishInteractiveTransition()
|
||||
}
|
||||
else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class func handleHideMenuTap(tap: UITapGestureRecognizer) {
|
||||
viewControllerForPresentedMenu?.dismissViewControllerAnimated(true, completion: nil)
|
||||
}
|
||||
|
||||
private class func visibleViewController() -> UIViewController? {
|
||||
return getVisibleViewControllerFrom(UIApplication.sharedApplication().keyWindow?.rootViewController)
|
||||
}
|
||||
|
||||
private class func getVisibleViewControllerFrom(viewController: UIViewController?) -> UIViewController? {
|
||||
if let navigationController = viewController as? UINavigationController {
|
||||
return getVisibleViewControllerFrom(navigationController.visibleViewController)
|
||||
} else if let tabBarController = viewController as? UITabBarController {
|
||||
return getVisibleViewControllerFrom(tabBarController.selectedViewController)
|
||||
} else if let presentedViewController = viewController?.presentedViewController {
|
||||
return getVisibleViewControllerFrom(presentedViewController)
|
||||
}
|
||||
|
||||
return viewController
|
||||
}
|
||||
|
||||
private class func hideMenuAppearance() {
|
||||
let mainViewController = viewControllerForPresentedMenu!
|
||||
let menuView = presentDirection == .Left ? menuLeftNavigationController!.view : menuRightNavigationController!.view
|
||||
menuView.transform = CGAffineTransformIdentity
|
||||
mainViewController.view.transform = CGAffineTransformIdentity
|
||||
mainViewController.view.alpha = 1
|
||||
tapView.frame = CGRectMake(0, 0, mainViewController.view.frame.width, mainViewController.view.frame.height)
|
||||
menuView.frame.origin.y = 0
|
||||
menuView.frame.size.width = menuWidth
|
||||
menuView.frame.size.height = mainViewController.view.frame.height
|
||||
statusBarView?.frame = UIApplication.sharedApplication().statusBarFrame
|
||||
statusBarView?.alpha = 0
|
||||
|
||||
switch menuPresentMode {
|
||||
|
||||
case .ViewSlideOut:
|
||||
menuView.alpha = 1 - menuAnimationFadeStrength
|
||||
menuView.frame.origin.x = presentDirection == .Left ? 0 : mainViewController.view.frame.width - menuWidth
|
||||
mainViewController.view.frame.origin.x = 0
|
||||
menuView.transform = CGAffineTransformMakeScale(menuAnimationShrinkStrength, menuAnimationShrinkStrength)
|
||||
|
||||
case .MenuSlideIn:
|
||||
menuView.alpha = 1
|
||||
menuView.frame.origin.x = presentDirection == .Left ? -menuView.frame.width : mainViewController.view.frame.width
|
||||
|
||||
case .MenuDissolveIn:
|
||||
menuView.alpha = 0
|
||||
menuView.frame.origin.x = presentDirection == .Left ? 0 : mainViewController.view.frame.width - menuWidth
|
||||
mainViewController.view.frame.origin.x = 0
|
||||
}
|
||||
}
|
||||
|
||||
private class func hideMenuComplete() {
|
||||
let mainViewController = viewControllerForPresentedMenu!
|
||||
let menuView = presentDirection == .Left ? menuLeftNavigationController!.view : menuRightNavigationController!.view
|
||||
tapView.removeFromSuperview()
|
||||
statusBarView?.removeFromSuperview()
|
||||
mainViewController.view.motionEffects.removeAll()
|
||||
mainViewController.view.layer.shadowOpacity = 0
|
||||
menuView.layer.shadowOpacity = 0
|
||||
NSNotificationCenter.defaultCenter().removeObserver(singleton)
|
||||
if let topNavigationController = mainViewController as? UINavigationController {
|
||||
topNavigationController.interactivePopGestureRecognizer!.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
private class func presentMenuAppearance(forSize size: CGSize = UIScreen.mainScreen().bounds.size) {
|
||||
let mainViewController = viewControllerForPresentedMenu!
|
||||
if let menuView = presentDirection == .Left ? menuLeftNavigationController?.view : menuRightNavigationController?.view {
|
||||
menuView.transform = CGAffineTransformIdentity
|
||||
mainViewController.view.transform = CGAffineTransformIdentity
|
||||
menuView.frame.size.width = menuWidth
|
||||
menuView.frame.size.height = size.height
|
||||
menuView.frame.origin.x = presentDirection == .Left ? 0 : size.width - menuWidth
|
||||
statusBarView?.frame = UIApplication.sharedApplication().statusBarFrame
|
||||
statusBarView?.alpha = 1
|
||||
|
||||
switch menuPresentMode {
|
||||
|
||||
case .ViewSlideOut:
|
||||
menuView.alpha = 1
|
||||
let direction:CGFloat = presentDirection == .Left ? 1 : -1
|
||||
mainViewController.view.frame.origin.x = direction * (menuView.frame.width)
|
||||
mainViewController.view.layer.shadowColor = menuShadowColor.CGColor
|
||||
mainViewController.view.layer.shadowRadius = menuShadowRadius
|
||||
mainViewController.view.layer.shadowOpacity = menuShadowOpacity
|
||||
mainViewController.view.layer.shadowOffset = CGSizeMake(0, 0)
|
||||
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
menuView.alpha = 1
|
||||
menuView.layer.shadowColor = menuShadowColor.CGColor
|
||||
menuView.layer.shadowRadius = menuShadowRadius
|
||||
menuView.layer.shadowOpacity = menuShadowOpacity
|
||||
menuView.layer.shadowOffset = CGSizeMake(0, 0)
|
||||
mainViewController.view.frame = CGRectMake(0, 0, size.width, size.height)
|
||||
mainViewController.view.transform = CGAffineTransformMakeScale(menuAnimationShrinkStrength, menuAnimationShrinkStrength)
|
||||
mainViewController.view.alpha = 1 - menuAnimationFadeStrength
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class func presentMenuComplete() {
|
||||
let mainViewController = viewControllerForPresentedMenu!
|
||||
switch menuPresentMode {
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
if menuParallaxStrength != 0 {
|
||||
let horizontal = UIInterpolatingMotionEffect(keyPath: "center.x", type: .TiltAlongHorizontalAxis)
|
||||
horizontal.minimumRelativeValue = -menuParallaxStrength
|
||||
horizontal.maximumRelativeValue = menuParallaxStrength
|
||||
|
||||
let vertical = UIInterpolatingMotionEffect(keyPath: "center.y", type: .TiltAlongVerticalAxis)
|
||||
vertical.minimumRelativeValue = -menuParallaxStrength
|
||||
vertical.maximumRelativeValue = menuParallaxStrength
|
||||
|
||||
let group = UIMotionEffectGroup()
|
||||
group.motionEffects = [horizontal, vertical]
|
||||
mainViewController.view.addMotionEffect(group)
|
||||
}
|
||||
case .ViewSlideOut: break;
|
||||
}
|
||||
if let topNavigationController = mainViewController as? UINavigationController {
|
||||
topNavigationController.interactivePopGestureRecognizer!.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: UIViewControllerAnimatedTransitioning protocol methods
|
||||
|
||||
// animate a change from one viewcontroller to another
|
||||
public func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
|
||||
|
||||
// get reference to our fromView, toView and the container view that we should perform the transition in
|
||||
let container = transitionContext.containerView()!
|
||||
if let menuBackgroundColor = SideMenuManager.menuAnimationBackgroundColor {
|
||||
container.backgroundColor = menuBackgroundColor
|
||||
}
|
||||
|
||||
// create a tuple of our screens
|
||||
let screens : (from:UIViewController, to:UIViewController) = (transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!, transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!)
|
||||
|
||||
// assign references to our menu view controller and the 'bottom' view controller from the tuple
|
||||
// remember that our menuViewController will alternate between the from and to view controller depending if we're presenting or dismissing
|
||||
let menuViewController = (!SideMenuManager.presenting ? screens.from : screens.to)
|
||||
let topViewController = !SideMenuManager.presenting ? screens.to : screens.from
|
||||
|
||||
let menuView = menuViewController.view
|
||||
let topView = topViewController.view
|
||||
|
||||
// prepare menu items to slide in
|
||||
if SideMenuManager.presenting {
|
||||
let tapView = UIView()
|
||||
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(SideMenuManager.self, action:"handleHideMenuPan:")
|
||||
let exitTapGesture = UITapGestureRecognizer()
|
||||
exitTapGesture.addTarget(SideMenuManager.self, action: "handleHideMenuTap:")
|
||||
tapView.addGestureRecognizer(exitPanGesture)
|
||||
tapView.addGestureRecognizer(exitTapGesture)
|
||||
|
||||
// add the both views to our view controller
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(menuView)
|
||||
container.addSubview(topView)
|
||||
topView.addSubview(tapView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
container.addSubview(topView)
|
||||
container.addSubview(tapView)
|
||||
container.addSubview(menuView)
|
||||
}
|
||||
|
||||
if SideMenuManager.menuFadeStatusBar {
|
||||
let blackBar = UIView()
|
||||
if let menuShrinkBackgroundColor = SideMenuManager.menuAnimationBackgroundColor {
|
||||
blackBar.backgroundColor = menuShrinkBackgroundColor
|
||||
} else {
|
||||
blackBar.backgroundColor = UIColor.blackColor()
|
||||
}
|
||||
blackBar.userInteractionEnabled = false
|
||||
container.addSubview(blackBar)
|
||||
SideMenuManager.statusBarView = blackBar
|
||||
}
|
||||
SideMenuManager.tapView = tapView
|
||||
|
||||
SideMenuManager.hideMenuAppearance() // offstage for interactive
|
||||
|
||||
NSNotificationCenter.defaultCenter().addObserver(SideMenuManager.singleton, selector:"applicationDidEnterBackgroundNotification", name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
}
|
||||
|
||||
// perform the animation!
|
||||
let duration = transitionDuration(transitionContext)
|
||||
let options: UIViewAnimationOptions = SideMenuManager.interactive ? .CurveLinear : .CurveEaseInOut
|
||||
UIView.animateWithDuration(duration, delay: 0, options: options, animations: { () -> Void in
|
||||
if SideMenuManager.presenting {
|
||||
SideMenuManager.presentMenuAppearance() // onstage items: slide in
|
||||
}
|
||||
else {
|
||||
SideMenuManager.hideMenuAppearance()
|
||||
}
|
||||
}) { (finished) -> Void in
|
||||
// if UIApplication.sharedApplication().visibleViewController!.preferredStatusBarStyle() != statusBarStyle {
|
||||
// // See http://www.openradar.me/21961293
|
||||
// print("Warning: do not change the status bar style while using interactive transitions or you risk transitions not properly completing.")
|
||||
// }
|
||||
// tell our transitionContext object that we've finished animating
|
||||
if transitionContext.transitionWasCancelled() {
|
||||
if SideMenuManager.presenting {
|
||||
SideMenuManager.hideMenuComplete()
|
||||
}
|
||||
transitionContext.completeTransition(false)
|
||||
} else {
|
||||
if SideMenuManager.presenting {
|
||||
SideMenuManager.presentMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(topView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
container.insertSubview(topView, atIndex: 0)
|
||||
}
|
||||
if let statusBarView = SideMenuManager.statusBarView {
|
||||
container.bringSubviewToFront(statusBarView)
|
||||
}
|
||||
} else {
|
||||
SideMenuManager.hideMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
menuView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return how many seconds the transiton animation will take
|
||||
public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
|
||||
return SideMenuManager.presenting ? SideMenuManager.menuAnimationPresentDuration : SideMenuManager.menuAnimationDismissDuration
|
||||
}
|
||||
|
||||
// MARK: UIViewControllerTransitioningDelegate protocol methods
|
||||
|
||||
// return the animataor when presenting a viewcontroller
|
||||
// rememeber that an animator (or animation controller) is any object that aheres to the UIViewControllerAnimatedTransitioning protocol
|
||||
public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
SideMenuManager.presenting = true
|
||||
SideMenuManager.presentDirection = presented == SideMenuManager.menuLeftNavigationController ? .Left : .Right
|
||||
return self
|
||||
}
|
||||
|
||||
// return the animator used when dismissing from a viewcontroller
|
||||
public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
SideMenuManager.presenting = false
|
||||
return self
|
||||
}
|
||||
|
||||
public func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
|
||||
// if our interactive flag is true, return the transition manager object
|
||||
// otherwise return nil
|
||||
return SideMenuManager.interactive ? SideMenuManager.singleton : nil
|
||||
}
|
||||
|
||||
public func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
|
||||
return SideMenuManager.interactive ? SideMenuManager.singleton : nil
|
||||
}
|
||||
|
||||
func applicationDidEnterBackgroundNotification() {
|
||||
if let menuViewController: UINavigationController = SideMenuManager.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
|
||||
SideMenuManager.hideMenuAppearance()
|
||||
SideMenuManager.hideMenuComplete()
|
||||
menuViewController.dismissViewControllerAnimated(false, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class UITableViewVibrantCell: UITableViewCell {
|
||||
|
||||
private var vibrancyView:UIVisualEffectView = UIVisualEffectView()
|
||||
private var vibrancySelectedBackgroundView:UIVisualEffectView = UIVisualEffectView()
|
||||
private var defaultSelectedBackgroundView:UIView?
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
vibrancyView.frame = bounds
|
||||
vibrancyView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
||||
for view in subviews {
|
||||
vibrancyView.contentView.addSubview(view)
|
||||
}
|
||||
addSubview(vibrancyView)
|
||||
|
||||
let blurSelectionEffect = UIBlurEffect(style: .Light)
|
||||
vibrancySelectedBackgroundView.effect = blurSelectionEffect
|
||||
defaultSelectedBackgroundView = selectedBackgroundView
|
||||
}
|
||||
|
||||
override public func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
if !UIAccessibilityIsReduceTransparencyEnabled() && SideMenuManager.menuBlurEffectStyle != nil {
|
||||
let blurEffect = UIBlurEffect(style: SideMenuManager.menuBlurEffectStyle!)
|
||||
vibrancyView.effect = UIVibrancyEffect(forBlurEffect: blurEffect)
|
||||
|
||||
if selectedBackgroundView != nil && selectedBackgroundView != vibrancySelectedBackgroundView {
|
||||
vibrancySelectedBackgroundView.contentView.addSubview(selectedBackgroundView!)
|
||||
selectedBackgroundView = vibrancySelectedBackgroundView
|
||||
}
|
||||
} else {
|
||||
vibrancyView.effect = nil
|
||||
selectedBackgroundView = defaultSelectedBackgroundView
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
//
|
||||
// SideMenuTransition.swift
|
||||
// Pods
|
||||
//
|
||||
// Created by Jon Kent on 1/14/16.
|
||||
//
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
|
||||
|
||||
private var presenting = false
|
||||
private var interactive = false
|
||||
private static weak var originalSuperview: UIView?
|
||||
|
||||
internal static let singleton = SideMenuTransition()
|
||||
internal static var presentDirection: UIRectEdge = .Left;
|
||||
internal static weak var tapView: UIView!
|
||||
internal static weak var statusBarView: UIView?
|
||||
|
||||
// prevent instantiation
|
||||
private override init() {}
|
||||
|
||||
private class var viewControllerForPresentedMenu: UIViewController? {
|
||||
get {
|
||||
return SideMenuManager.menuLeftNavigationController?.presentingViewController != nil ? SideMenuManager.menuLeftNavigationController?.presentingViewController : SideMenuManager.menuRightNavigationController?.presentingViewController
|
||||
}
|
||||
}
|
||||
|
||||
private class var visibleViewController: UIViewController? {
|
||||
get {
|
||||
return getVisibleViewControllerFromViewController(UIApplication.sharedApplication().keyWindow?.rootViewController)
|
||||
}
|
||||
}
|
||||
|
||||
private class func getVisibleViewControllerFromViewController(viewController: UIViewController?) -> UIViewController? {
|
||||
if let navigationController = viewController as? UINavigationController {
|
||||
return getVisibleViewControllerFromViewController(navigationController.visibleViewController)
|
||||
} else if let tabBarController = viewController as? UITabBarController {
|
||||
return getVisibleViewControllerFromViewController(tabBarController.selectedViewController)
|
||||
} else if let presentedViewController = viewController?.presentedViewController {
|
||||
return getVisibleViewControllerFromViewController(presentedViewController)
|
||||
}
|
||||
|
||||
return viewController
|
||||
}
|
||||
|
||||
class func handlePresentMenuPan(pan: UIPanGestureRecognizer) {
|
||||
// how much distance have we panned in reference to the parent view?
|
||||
if let view = viewControllerForPresentedMenu != nil ? viewControllerForPresentedMenu?.view : pan.view {
|
||||
let transform = view.transform
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let translation = pan.translationInView(pan.view!)
|
||||
view.transform = transform
|
||||
|
||||
// do some math to translate this to a percentage based value
|
||||
if !singleton.interactive {
|
||||
if translation.x == 0 {
|
||||
return // not sure which way the user is swiping yet, so do nothing
|
||||
}
|
||||
|
||||
if let edge = pan as? UIScreenEdgePanGestureRecognizer {
|
||||
SideMenuTransition.presentDirection = edge.edges == .Left ? .Left : .Right
|
||||
} else {
|
||||
SideMenuTransition.presentDirection = translation.x > 0 ? .Left : .Right
|
||||
}
|
||||
|
||||
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
|
||||
singleton.interactive = true
|
||||
if let visibleViewController = visibleViewController {
|
||||
visibleViewController.presentViewController(menuViewController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? 1 : -1
|
||||
let distance = translation.x / SideMenuManager.menuWidth
|
||||
// now lets deal with different states that the gesture recognizer sends
|
||||
switch (pan.state) {
|
||||
case .Began, .Changed:
|
||||
if pan is UIScreenEdgePanGestureRecognizer {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
} else if distance > 0 && SideMenuTransition.presentDirection == .Right && SideMenuManager.menuLeftNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Left
|
||||
singleton.cancelInteractiveTransition()
|
||||
viewControllerForPresentedMenu?.presentViewController(SideMenuManager.menuLeftNavigationController!, animated: true, completion: nil)
|
||||
} else if distance < 0 && SideMenuTransition.presentDirection == .Left && SideMenuManager.menuRightNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Right
|
||||
singleton.cancelInteractiveTransition()
|
||||
viewControllerForPresentedMenu?.presentViewController(SideMenuManager.menuRightNavigationController!, animated: true, completion: nil)
|
||||
} else {
|
||||
singleton.updateInteractiveTransition(min(distance * direction, 1))
|
||||
}
|
||||
default:
|
||||
singleton.interactive = false
|
||||
view.transform = CGAffineTransformIdentity
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
view.transform = transform
|
||||
if velocity >= 100 || velocity >= -50 && abs(distance) >= 0.5 {
|
||||
singleton.finishInteractiveTransition()
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class func handleHideMenuPan(pan: UIPanGestureRecognizer) {
|
||||
let translation = pan.translationInView(pan.view!)
|
||||
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? -1 : 1
|
||||
let distance = translation.x / SideMenuManager.menuWidth * direction
|
||||
|
||||
switch (pan.state) {
|
||||
|
||||
case .Began:
|
||||
singleton.interactive = true
|
||||
viewControllerForPresentedMenu?.dismissViewControllerAnimated(true, completion: nil)
|
||||
case .Changed:
|
||||
singleton.updateInteractiveTransition(max(min(distance, 1), 0))
|
||||
default:
|
||||
singleton.interactive = false
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
if velocity >= 100 || velocity >= -50 && distance >= 0.5 {
|
||||
singleton.finishInteractiveTransition()
|
||||
}
|
||||
else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class func handleHideMenuTap(tap: UITapGestureRecognizer) {
|
||||
viewControllerForPresentedMenu?.dismissViewControllerAnimated(true, completion: nil)
|
||||
}
|
||||
|
||||
internal class func hideMenuStart() {
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController!.view : SideMenuManager.menuRightNavigationController!.view
|
||||
menuView.transform = CGAffineTransformIdentity
|
||||
mainViewController.view.transform = CGAffineTransformIdentity
|
||||
mainViewController.view.alpha = 1
|
||||
SideMenuTransition.tapView.frame = CGRectMake(0, 0, mainViewController.view.frame.width, mainViewController.view.frame.height)
|
||||
menuView.frame.origin.y = 0
|
||||
menuView.frame.size.width = SideMenuManager.menuWidth
|
||||
menuView.frame.size.height = mainViewController.view.frame.height
|
||||
SideMenuTransition.statusBarView?.frame = UIApplication.sharedApplication().statusBarFrame
|
||||
SideMenuTransition.statusBarView?.alpha = 0
|
||||
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
|
||||
case .ViewSlideOut:
|
||||
menuView.alpha = 1 - SideMenuManager.menuAnimationFadeStrength
|
||||
menuView.frame.origin.x = SideMenuTransition.presentDirection == .Left ? 0 : mainViewController.view.frame.width - SideMenuManager.menuWidth
|
||||
mainViewController.view.frame.origin.x = 0
|
||||
menuView.transform = CGAffineTransformMakeScale(SideMenuManager.menuAnimationShrinkStrength, SideMenuManager.menuAnimationShrinkStrength)
|
||||
|
||||
case .MenuSlideIn:
|
||||
menuView.alpha = 1
|
||||
menuView.frame.origin.x = SideMenuTransition.presentDirection == .Left ? -menuView.frame.width : mainViewController.view.frame.width
|
||||
|
||||
case .MenuDissolveIn:
|
||||
menuView.alpha = 0
|
||||
menuView.frame.origin.x = SideMenuTransition.presentDirection == .Left ? 0 : mainViewController.view.frame.width - SideMenuManager.menuWidth
|
||||
mainViewController.view.frame.origin.x = 0
|
||||
}
|
||||
}
|
||||
|
||||
internal class func hideMenuComplete() {
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController!.view : SideMenuManager.menuRightNavigationController!.view
|
||||
SideMenuTransition.tapView.removeFromSuperview()
|
||||
SideMenuTransition.statusBarView?.removeFromSuperview()
|
||||
mainViewController.view.motionEffects.removeAll()
|
||||
mainViewController.view.layer.shadowOpacity = 0
|
||||
menuView.layer.shadowOpacity = 0
|
||||
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||
if let topNavigationController = mainViewController as? UINavigationController {
|
||||
topNavigationController.interactivePopGestureRecognizer!.enabled = true
|
||||
}
|
||||
originalSuperview?.addSubview(mainViewController.view)
|
||||
}
|
||||
|
||||
internal class func presentMenuStart(forSize size: CGSize = UIScreen.mainScreen().bounds.size) {
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
if let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController?.view : SideMenuManager.menuRightNavigationController?.view {
|
||||
menuView.transform = CGAffineTransformIdentity
|
||||
mainViewController.view.transform = CGAffineTransformIdentity
|
||||
menuView.frame.size.width = SideMenuManager.menuWidth
|
||||
menuView.frame.size.height = size.height
|
||||
menuView.frame.origin.x = SideMenuTransition.presentDirection == .Left ? 0 : size.width - SideMenuManager.menuWidth
|
||||
SideMenuTransition.statusBarView?.frame = UIApplication.sharedApplication().statusBarFrame
|
||||
SideMenuTransition.statusBarView?.alpha = 1
|
||||
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
|
||||
case .ViewSlideOut:
|
||||
menuView.alpha = 1
|
||||
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? 1 : -1
|
||||
mainViewController.view.frame.origin.x = direction * (menuView.frame.width)
|
||||
mainViewController.view.layer.shadowColor = SideMenuManager.menuShadowColor.CGColor
|
||||
mainViewController.view.layer.shadowRadius = SideMenuManager.menuShadowRadius
|
||||
mainViewController.view.layer.shadowOpacity = SideMenuManager.menuShadowOpacity
|
||||
mainViewController.view.layer.shadowOffset = CGSizeMake(0, 0)
|
||||
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
menuView.alpha = 1
|
||||
menuView.layer.shadowColor = SideMenuManager.menuShadowColor.CGColor
|
||||
menuView.layer.shadowRadius = SideMenuManager.menuShadowRadius
|
||||
menuView.layer.shadowOpacity = SideMenuManager.menuShadowOpacity
|
||||
menuView.layer.shadowOffset = CGSizeMake(0, 0)
|
||||
mainViewController.view.frame = CGRectMake(0, 0, size.width, size.height)
|
||||
mainViewController.view.transform = CGAffineTransformMakeScale(SideMenuManager.menuAnimationShrinkStrength, SideMenuManager.menuAnimationShrinkStrength)
|
||||
mainViewController.view.alpha = 1 - SideMenuManager.menuAnimationFadeStrength
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class func presentMenuComplete() {
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
if SideMenuManager.menuParallaxStrength != 0 {
|
||||
let horizontal = UIInterpolatingMotionEffect(keyPath: "center.x", type: .TiltAlongHorizontalAxis)
|
||||
horizontal.minimumRelativeValue = -SideMenuManager.menuParallaxStrength
|
||||
horizontal.maximumRelativeValue = SideMenuManager.menuParallaxStrength
|
||||
|
||||
let vertical = UIInterpolatingMotionEffect(keyPath: "center.y", type: .TiltAlongVerticalAxis)
|
||||
vertical.minimumRelativeValue = -SideMenuManager.menuParallaxStrength
|
||||
vertical.maximumRelativeValue = SideMenuManager.menuParallaxStrength
|
||||
|
||||
let group = UIMotionEffectGroup()
|
||||
group.motionEffects = [horizontal, vertical]
|
||||
mainViewController.view.addMotionEffect(group)
|
||||
}
|
||||
case .ViewSlideOut: break;
|
||||
}
|
||||
if let topNavigationController = mainViewController as? UINavigationController {
|
||||
topNavigationController.interactivePopGestureRecognizer!.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: UIViewControllerAnimatedTransitioning protocol methods
|
||||
|
||||
// animate a change from one viewcontroller to another
|
||||
internal func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
|
||||
|
||||
let statusBarStyle = SideMenuTransition.visibleViewController?.preferredStatusBarStyle()
|
||||
|
||||
// get reference to our fromView, toView and the container view that we should perform the transition in
|
||||
let container = transitionContext.containerView()!
|
||||
if let menuBackgroundColor = SideMenuManager.menuAnimationBackgroundColor {
|
||||
container.backgroundColor = menuBackgroundColor
|
||||
}
|
||||
|
||||
// create a tuple of our screens
|
||||
let screens : (from:UIViewController, to:UIViewController) = (transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!, transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!)
|
||||
|
||||
// assign references to our menu view controller and the 'bottom' view controller from the tuple
|
||||
// remember that our menuViewController will alternate between the from and to view controller depending if we're presenting or dismissing
|
||||
let menuViewController = (!presenting ? screens.from : screens.to)
|
||||
let topViewController = !presenting ? screens.to : screens.from
|
||||
|
||||
let menuView = menuViewController.view
|
||||
let topView = topViewController.view
|
||||
|
||||
// prepare menu items to slide in
|
||||
if presenting {
|
||||
let tapView = UIView()
|
||||
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:"handleHideMenuPan:")
|
||||
let exitTapGesture = UITapGestureRecognizer()
|
||||
exitTapGesture.addTarget(SideMenuTransition.self, action: "handleHideMenuTap:")
|
||||
tapView.addGestureRecognizer(exitPanGesture)
|
||||
tapView.addGestureRecognizer(exitTapGesture)
|
||||
SideMenuTransition.tapView = tapView
|
||||
|
||||
SideMenuTransition.originalSuperview = topView.superview
|
||||
|
||||
// add the both views to our view controller
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(menuView)
|
||||
container.addSubview(topView)
|
||||
topView.addSubview(tapView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
container.addSubview(topView)
|
||||
container.addSubview(tapView)
|
||||
container.addSubview(menuView)
|
||||
}
|
||||
|
||||
if SideMenuManager.menuFadeStatusBar {
|
||||
let blackBar = UIView()
|
||||
if let menuShrinkBackgroundColor = SideMenuManager.menuAnimationBackgroundColor {
|
||||
blackBar.backgroundColor = menuShrinkBackgroundColor
|
||||
} else {
|
||||
blackBar.backgroundColor = UIColor.blackColor()
|
||||
}
|
||||
blackBar.userInteractionEnabled = false
|
||||
container.addSubview(blackBar)
|
||||
SideMenuTransition.statusBarView = blackBar
|
||||
}
|
||||
|
||||
SideMenuTransition.hideMenuStart() // offstage for interactive
|
||||
|
||||
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||
NSNotificationCenter.defaultCenter().addObserver(SideMenuTransition.singleton, selector:"applicationDidEnterBackgroundNotification", name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
}
|
||||
|
||||
// perform the animation!
|
||||
let duration = transitionDuration(transitionContext)
|
||||
let options: UIViewAnimationOptions = interactive ? .CurveLinear : .CurveEaseInOut
|
||||
UIView.animateWithDuration(duration, delay: 0, options: options, animations: { () -> Void in
|
||||
if self.presenting {
|
||||
SideMenuTransition.presentMenuStart() // onstage items: slide in
|
||||
}
|
||||
else {
|
||||
SideMenuTransition.hideMenuStart()
|
||||
}
|
||||
}) { (finished) -> Void in
|
||||
if SideMenuTransition.visibleViewController?.preferredStatusBarStyle() != statusBarStyle {
|
||||
print("Warning: do not change the status bar style while using custom transitions or you risk transitions not properly completing and locking up the UI. See http://www.openradar.me/21961293")
|
||||
}
|
||||
// tell our transitionContext object that we've finished animating
|
||||
if transitionContext.transitionWasCancelled() {
|
||||
if self.presenting {
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
}
|
||||
transitionContext.completeTransition(false)
|
||||
} else {
|
||||
if self.presenting {
|
||||
SideMenuTransition.presentMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(topView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
container.insertSubview(topView, atIndex: 0)
|
||||
}
|
||||
if let statusBarView = SideMenuTransition.statusBarView {
|
||||
container.bringSubviewToFront(statusBarView)
|
||||
}
|
||||
} else {
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
menuView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return how many seconds the transiton animation will take
|
||||
internal func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
|
||||
return presenting ? SideMenuManager.menuAnimationPresentDuration : SideMenuManager.menuAnimationDismissDuration
|
||||
}
|
||||
|
||||
// MARK: UIViewControllerTransitioningDelegate protocol methods
|
||||
|
||||
// return the animataor when presenting a viewcontroller
|
||||
// rememeber that an animator (or animation controller) is any object that aheres to the UIViewControllerAnimatedTransitioning protocol
|
||||
internal func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
self.presenting = true
|
||||
SideMenuTransition.presentDirection = presented == SideMenuManager.menuLeftNavigationController ? .Left : .Right
|
||||
return self
|
||||
}
|
||||
|
||||
// return the animator used when dismissing from a viewcontroller
|
||||
internal func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
presenting = false
|
||||
return self
|
||||
}
|
||||
|
||||
internal func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
|
||||
// if our interactive flag is true, return the transition manager object
|
||||
// otherwise return nil
|
||||
return interactive ? SideMenuTransition.singleton : nil
|
||||
}
|
||||
|
||||
internal func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
|
||||
return interactive ? SideMenuTransition.singleton : nil
|
||||
}
|
||||
|
||||
internal func applicationDidEnterBackgroundNotification() {
|
||||
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
|
||||
SideMenuTransition.hideMenuStart()
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
menuViewController.dismissViewControllerAnimated(false, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
//
|
||||
// UISideMenuNavigationController.swift
|
||||
//
|
||||
// Created by Jon Kent on 1/14/16.
|
||||
// Copyright © 2016 Jon Kent. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public class UISideMenuNavigationController: UINavigationController {
|
||||
|
||||
public override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
// if this isn't set here, segues cause viewWillAppear and viewDidAppear to be called twice
|
||||
// likely because the transition completes and the presentingViewController is added back
|
||||
// into view for the default transition style.
|
||||
modalPresentationStyle = .OverFullScreen
|
||||
}
|
||||
|
||||
@IBInspectable public var leftSide:Bool = false {
|
||||
didSet {
|
||||
if isViewLoaded() { // suppress warnings
|
||||
didSetSide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
didSetSide()
|
||||
}
|
||||
|
||||
private func didSetSide() {
|
||||
if leftSide {
|
||||
SideMenuManager.menuLeftNavigationController = self
|
||||
} else {
|
||||
SideMenuManager.menuRightNavigationController = self
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
// we had presented a view before, so lets dismiss ourselves as already acted upon
|
||||
if view.hidden {
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
dismissViewControllerAnimated(false, completion: { () -> Void in
|
||||
self.view.hidden = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewWillDisappear(animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
// when presenting a view controller from the menu, the menu view gets moved into another transition view above our transition container
|
||||
// which can break the visual layout we had before. So, we move the menu view back to its original transition view to preserve it.
|
||||
if !isBeingDismissed() {
|
||||
if let mainView = presentingViewController?.view {
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
mainView.superview?.insertSubview(view, belowSubview: mainView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
mainView.superview?.insertSubview(view, aboveSubview: SideMenuTransition.tapView)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewDidDisappear(animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
|
||||
// we're presenting a view controller from the menu, so we need to hide the menu so it isn't g when the presented view is dismissed.
|
||||
if !isBeingDismissed() {
|
||||
view.hidden = true
|
||||
SideMenuTransition.hideMenuStart()
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
|
||||
|
||||
// don't bother resizing if the view isn't visible
|
||||
if view.hidden {
|
||||
return
|
||||
}
|
||||
|
||||
SideMenuTransition.statusBarView?.hidden = true
|
||||
coordinator.animateAlongsideTransition({ (context) -> Void in
|
||||
SideMenuTransition.presentMenuStart(forSize: size)
|
||||
}) { (context) -> Void in
|
||||
SideMenuTransition.statusBarView?.hidden = false
|
||||
}
|
||||
}
|
||||
|
||||
override public func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController,
|
||||
presentingViewController = menuViewController.presentingViewController as? UINavigationController {
|
||||
presentingViewController.prepareForSegue(segue, sender: sender)
|
||||
}
|
||||
}
|
||||
|
||||
override public func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
|
||||
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController,
|
||||
presentingViewController = menuViewController.presentingViewController as? UINavigationController {
|
||||
return presentingViewController.shouldPerformSegueWithIdentifier(identifier, sender: sender)
|
||||
}
|
||||
|
||||
return super.shouldPerformSegueWithIdentifier(identifier, sender: sender)
|
||||
}
|
||||
|
||||
override public func pushViewController(viewController: UIViewController, animated: Bool) {
|
||||
if let menuViewController: UINavigationController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController {
|
||||
if let presentingViewController = menuViewController.presentingViewController as? UINavigationController {
|
||||
|
||||
// to avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
|
||||
// is dismissed after showing the appropriate screen
|
||||
CATransaction.begin()
|
||||
CATransaction.setCompletionBlock( { () -> Void in
|
||||
self.dismissViewControllerAnimated(true, completion: nil)
|
||||
self.visibleViewController?.viewWillAppear(false) // Hack: force selection to get cleared on UITableViewControllers when reappearing using custom transitions
|
||||
})
|
||||
|
||||
UIView.animateWithDuration(SideMenuManager.menuAnimationDismissDuration, animations: { () -> Void in
|
||||
SideMenuTransition.hideMenuStart()
|
||||
})
|
||||
|
||||
if SideMenuManager.menuAllowPopIfPossible {
|
||||
for subViewController in presentingViewController.viewControllers {
|
||||
if subViewController.dynamicType == viewController.dynamicType {
|
||||
presentingViewController.popToViewController(subViewController, animated: animated)
|
||||
CATransaction.commit()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if !SideMenuManager.menuAllowPushOfSameClassTwice {
|
||||
if presentingViewController.viewControllers.last?.dynamicType == viewController.dynamicType {
|
||||
CATransaction.commit()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
presentingViewController.pushViewController(viewController, animated: animated)
|
||||
CATransaction.commit()
|
||||
} else {
|
||||
menuViewController.presentViewController(viewController, animated: animated, completion: nil)
|
||||
print("Warning: attempted to push a ViewController from a ViewController that doesn't have a NavigationController. It will be presented it instead.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// UITableViewVibrantCell.swift
|
||||
// Pods
|
||||
//
|
||||
// Created by Jon Kent on 1/14/16.
|
||||
//
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public class UITableViewVibrantCell: UITableViewCell {
|
||||
|
||||
private var vibrancyView:UIVisualEffectView = UIVisualEffectView()
|
||||
private var vibrancySelectedBackgroundView:UIVisualEffectView = UIVisualEffectView()
|
||||
private var defaultSelectedBackgroundView:UIView?
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
vibrancyView.frame = bounds
|
||||
vibrancyView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
||||
for view in subviews {
|
||||
vibrancyView.contentView.addSubview(view)
|
||||
}
|
||||
addSubview(vibrancyView)
|
||||
|
||||
let blurSelectionEffect = UIBlurEffect(style: .Light)
|
||||
vibrancySelectedBackgroundView.effect = blurSelectionEffect
|
||||
defaultSelectedBackgroundView = selectedBackgroundView
|
||||
}
|
||||
|
||||
override public func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
if !UIAccessibilityIsReduceTransparencyEnabled() && SideMenuManager.menuBlurEffectStyle != nil {
|
||||
let blurEffect = UIBlurEffect(style: SideMenuManager.menuBlurEffectStyle!)
|
||||
vibrancyView.effect = UIVibrancyEffect(forBlurEffect: blurEffect)
|
||||
|
||||
if selectedBackgroundView != nil && selectedBackgroundView != vibrancySelectedBackgroundView {
|
||||
vibrancySelectedBackgroundView.contentView.addSubview(selectedBackgroundView!)
|
||||
selectedBackgroundView = vibrancySelectedBackgroundView
|
||||
}
|
||||
} else {
|
||||
vibrancyView.effect = nil
|
||||
selectedBackgroundView = defaultSelectedBackgroundView
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,43 +3,75 @@
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
|
||||
SideMenu is a simple and versatile side menu control written in Swift. The are three standard animation styles to choose from along with several other options for further customization if desired.
|
||||
### If you like SideMenu, give it a ★ at the top right of this page.
|
||||
|
||||
SideMenu is a simple and versatile side menu control written in Swift.
|
||||
- [x] **It can be implemented in storyboard without a single line of [code](#code-less-storyboard-implementation).**
|
||||
- [x] Three standard animation styles to choose from.
|
||||
- [x] Highly customizable without needing to write tons of custom code.
|
||||
- [x] Supports continuous swiping between each side menu in a single gesture.
|
||||
- [x] Menus can be presented and dismissed the same as any other View Controller since this control uses custom transitions.
|
||||
|
||||
Check out the example project or this [interactive demo](https://appetize.io/app/42d6b8teuaej2wcday76jqwrcc) to see it in action!
|
||||
|
||||

|
||||
|
||||
## Requirements
|
||||
* Xcode 7 or higher
|
||||
* iOS 8 or higher
|
||||
* ARC
|
||||
- [x] iOS 8 or higher
|
||||
|
||||
## Installation
|
||||
|
||||
SideMenu is available through [CocoaPods](http://cocoapods.org). To install
|
||||
it, simply add the following line to your Podfile:
|
||||
### CocoaPods
|
||||
|
||||
[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:
|
||||
|
||||
```bash
|
||||
$ gem install cocoapods
|
||||
```
|
||||
|
||||
To integrate SideMenu into your Xcode project using CocoaPods, specify it in your `Podfile`:
|
||||
|
||||
```ruby
|
||||
pod "SideMenu"
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
platform :ios, '8.0'
|
||||
use_frameworks!
|
||||
|
||||
pod 'SideMenu'
|
||||
```
|
||||
|
||||
Then, run the following command:
|
||||
|
||||
```bash
|
||||
$ pod install
|
||||
```
|
||||
|
||||
## Usage
|
||||
SideMenu is highly customizable, but can also be implemented in storyboard without a single line of code. Check out the example project to see it in action.
|
||||
### Code-less Storyboard Implementation
|
||||
1. Create a Navigation Controller for a side menu. Set the custom class of the Navigation Controller to be `UISideMenuNavigationController` in the **Identity Inspector**. Create a Root View Controller for the Navigation Controller (shown as a UITableViewController below). Set up any Triggered Segues you want in that View Controller.
|
||||

|
||||
|
||||
### Storyboard
|
||||
1. Create a Navigation Controller. Set the custom class of the Navigation Controller to be `UILeftMenuNavigationController` or `UIRightMenuNavigationController` (whichever you prefer) in the **Identity Inspector**.
|
||||
2. Create a root View Controller for the Navigation Controller in step 1. Set up any Triggered Segues you want in that View Controller.
|
||||
3. From any View Controller, add a UIButton or UIBarButton. Set that button's Triggered Segues action to modally present the Navigation Controller from step 1.
|
||||
2. Set the `Left Side` property of the `UISideMenuNavigationController` to On if you want it to appear from the left side of the screen, or Off/Default if you want it to appear from the right side.
|
||||

|
||||
|
||||
*Note: you can only enable gestures with code.*
|
||||
3. Add a UIButton or UIBarButton to a View Controller that you want to display the menu from. Set that button's Triggered Segues action to modally present the Navigation Controller from step 1.
|
||||

|
||||
|
||||
That's it. *Note: you can only enable gestures in code.*
|
||||
### Code Implementation
|
||||
First:
|
||||
```swift
|
||||
import SideMenu
|
||||
```
|
||||
|
||||
### Code
|
||||
In your View Controller's `viewDidLoad` event, do something like this:
|
||||
``` swift
|
||||
// Define the menus
|
||||
let leftMenuNavigationController = UILeftMenuNavigationController()
|
||||
// UILeftMenuNavigationController is a subclass of UINavigationController, so do any additional configuration of it here
|
||||
let leftMenuNavigationController = UIMenuNavigationController()
|
||||
leftMenuNavigationController.leftSide = true
|
||||
// UIMenuNavigationController is a subclass of UINavigationController, so do any additional configuration of it here like setting its viewControllers.
|
||||
SideMenuManager.menuLeftNavigationController = leftMenuNavigationController
|
||||
let rightMenuNavigationController = UIRightMenuNavigationController()
|
||||
// UIRightMenuNavigationController is a subclass of UINavigationController, so do any additional configuration of it here
|
||||
let rightMenuNavigationController = UIMenuNavigationController()
|
||||
// UIMenuNavigationController is a subclass of UINavigationController, so do any additional configuration of it here like setting its viewControllers.
|
||||
SideMenuManager.menuRightNavigationController = rightMenuNavigationController
|
||||
|
||||
// Enable gestures. The left and/or right menus must be set up above for these to work.
|
||||
@@ -51,7 +83,7 @@ Then from a button, do something like this:
|
||||
``` swift
|
||||
presentViewController(SideMenuManager.menuLeftNavigationController!, animated: true, completion: nil)
|
||||
```
|
||||
|
||||
That's it.
|
||||
### Customization
|
||||
Just type `SideMenuManager.menu...` and code completion will show you everything you can customize (defaults are shown below for reference):
|
||||
``` swift
|
||||
@@ -79,7 +111,7 @@ menuAddPanGestureToPresent(toView toView: UIView) -> UIPanGestureRecognizer
|
||||
```
|
||||
|
||||
## Known Issues
|
||||
Don't try to change the status bar appearance when presenting a menu. When used with quick gestures/animations, it causes the presentation animation to not complete properly and locks up the UI. See [radar 21961293](http://www.openradar.me/21961293) for more information.
|
||||
Don't try to change the status bar appearance when presenting a menu. When used with quick gestures/animations, it causes the presentation animation to not complete properly and locks the UI. See [radar 21961293](http://www.openradar.me/21961293) for more information.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SideMenu"
|
||||
s.version = "0.1.0"
|
||||
s.summary = "SideMenu is a simple and versatile side menu control."
|
||||
s.version = "0.1.6"
|
||||
s.summary = "Simple side menu control in Swift inspired by Facebook. Right and Left sides. No coding required."
|
||||
|
||||
# This description is used to generate tags and improve search results.
|
||||
# * Think: What does it do? Why did you write it? What is the focus?
|
||||
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
|
||||
DESC
|
||||
|
||||
s.homepage = "https://github.com/jonkykong/SideMenu"
|
||||
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
|
||||
s.screenshot = "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Preview.gif"
|
||||
s.license = 'MIT'
|
||||
s.author = { "jonkykong" => "jonk@jonked.com" }
|
||||
s.source = { :git => "https://github.com/jonkykong/SideMenu.git", :tag => s.version.to_s }
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 134 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 221 KiB |
Reference in New Issue
Block a user