Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e70f37f7b4 | |||
| 21e873cc68 | |||
| d81eb6277d | |||
| 2f6a1b8e6c | |||
| 7d766813fd | |||
| 78fad19e6f | |||
| e91b9be969 | |||
| 02252bc035 | |||
| 4a658269a6 | |||
| b5342a1c7c | |||
| bd2dc72a37 | |||
| 58a1e19737 | |||
| 046c09765f | |||
| dbeb741505 | |||
| 2663b967d7 | |||
| 7a601b78b7 | |||
| 356f7c16e2 | |||
| e512ae54be | |||
| 2029af7894 | |||
| 0be7f0bc31 | |||
| d4732fbae5 | |||
| 07f6dff8e8 | |||
| a195757c1d | |||
| 68648ef3f1 | |||
| fec44d0cc2 | |||
| 4da251f6ea | |||
| ddbc431d45 | |||
| 405a3ea56d | |||
| 031e3bcfba | |||
| c08c9a92ec | |||
| f980f558b4 | |||
| b183c95efd | |||
| 110eca43d3 | |||
| 8598050032 | |||
| 08e482c412 | |||
| 8b833b9044 | |||
| b1f51cdcca | |||
| 6a33fea711 | |||
| 2e5b209a0c | |||
| 5463a48207 | |||
| ab5d7a17d6 | |||
| 339468f95d | |||
| 933b9e93f3 | |||
| ab420fa769 | |||
| fe52a16565 | |||
| 7541ac0ef7 | |||
| 448faae85c | |||
| 3b2e3454cf | |||
| 4926721a42 |
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- SideMenu (1.0.0)
|
||||
- SideMenu (1.0.3)
|
||||
|
||||
DEPENDENCIES:
|
||||
- SideMenu (from `../`)
|
||||
@@ -9,6 +9,6 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
SideMenu: 97ed15625c7b86c4090c2e931a3e5ee89f050afa
|
||||
SideMenu: 166ea23f143a8df84d0cf2170057793e26f0ba9e
|
||||
|
||||
COCOAPODS: 0.39.0
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "SideMenu",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.3",
|
||||
"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",
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/jonkykong/SideMenu.git",
|
||||
"tag": "1.0.0"
|
||||
"tag": "1.0.3"
|
||||
},
|
||||
"platforms": {
|
||||
"ios": "8.0"
|
||||
|
||||
Generated
+2
-2
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- SideMenu (1.0.0)
|
||||
- SideMenu (1.0.3)
|
||||
|
||||
DEPENDENCIES:
|
||||
- SideMenu (from `../`)
|
||||
@@ -9,6 +9,6 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
SideMenu: 97ed15625c7b86c4090c2e931a3e5ee89f050afa
|
||||
SideMenu: 166ea23f143a8df84d0cf2170057793e26f0ba9e
|
||||
|
||||
COCOAPODS: 0.39.0
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<string>1.0.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
84788C781C2B9F1E00C4DAF4 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84788C741C2B9F1E00C4DAF4 /* MainViewController.swift */; };
|
||||
84788C7B1C2B9FAB00C4DAF4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84788C7A1C2B9FAB00C4DAF4 /* AppDelegate.swift */; };
|
||||
84788C7D1C2BCDEB00C4DAF4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84788C7C1C2BCDEB00C4DAF4 /* Main.storyboard */; };
|
||||
847D41DA1CB498BE0079C28F /* SideMenuTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847D41D91CB498BE0079C28F /* SideMenuTableView.swift */; };
|
||||
A91D298EBD84AC675595CCA0 /* Pods_SideMenu_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FB2E5A68EB8A0DF6615E0 /* Pods_SideMenu_Example.framework */; };
|
||||
AFA077A8EC0A5A74F8D6FF18 /* Pods_SideMenu_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8960F7A82F3CB64025C48B38 /* Pods_SideMenu_Tests.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
@@ -45,6 +46,7 @@
|
||||
84788C741C2B9F1E00C4DAF4 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
|
||||
84788C7A1C2B9FAB00C4DAF4 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
84788C7C1C2BCDEB00C4DAF4 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
|
||||
847D41D91CB498BE0079C28F /* SideMenuTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideMenuTableView.swift; sourceTree = "<group>"; };
|
||||
8960F7A82F3CB64025C48B38 /* Pods_SideMenu_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SideMenu_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A20C1DB98DEF29F3CE8D592A /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
|
||||
B02FB2E5A68EB8A0DF6615E0 /* Pods_SideMenu_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SideMenu_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -109,6 +111,7 @@
|
||||
84788C741C2B9F1E00C4DAF4 /* MainViewController.swift */,
|
||||
84430B121C31F6D100858AA8 /* PresentedViewController.swift */,
|
||||
84788C7C1C2BCDEB00C4DAF4 /* Main.storyboard */,
|
||||
847D41D91CB498BE0079C28F /* SideMenuTableView.swift */,
|
||||
607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
|
||||
607FACD31AFB9204008FA782 /* Supporting Files */,
|
||||
);
|
||||
@@ -362,6 +365,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
847D41DA1CB498BE0079C28F /* SideMenuTableView.swift in Sources */,
|
||||
84788C7B1C2B9FAB00C4DAF4 /* AppDelegate.swift in Sources */,
|
||||
84430B131C31F6D100858AA8 /* PresentedViewController.swift in Sources */,
|
||||
84788C781C2B9F1E00C4DAF4 /* MainViewController.swift in Sources */,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "saturn.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 573 KiB |
@@ -37,6 +37,7 @@
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?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">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" 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"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@@ -63,17 +63,6 @@
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" translatesAutoresizingMaskIntoConstraints="NO" id="KV2-tN-Aff">
|
||||
<rect key="frame" x="20" y="37" width="280" height="29"/>
|
||||
<segments>
|
||||
<segment title="Slide In"/>
|
||||
<segment title="Slide Out"/>
|
||||
<segment title="Dissolve"/>
|
||||
</segments>
|
||||
<connections>
|
||||
<action selector="changeSegment:" destination="QHN-nZ-kbB" eventType="valueChanged" id="xYG-CU-6tx"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<slider opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="Osf-2d-Znm">
|
||||
<rect key="frame" x="18" y="234" width="284" height="31"/>
|
||||
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="calibratedRGB"/>
|
||||
@@ -93,7 +82,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.001" 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="2" 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>
|
||||
@@ -113,8 +102,8 @@
|
||||
<action selector="changeSlider:" destination="QHN-nZ-kbB" eventType="valueChanged" id="CFn-3w-HeP"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Shrink Strength" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tsg-30-YHs">
|
||||
<rect key="frame" x="20" y="339" width="167" height="20.5"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Transform Scale Factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tsg-30-YHs">
|
||||
<rect key="frame" x="20" y="339" width="225" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -144,6 +133,18 @@
|
||||
<action selector="changeSwitch:" destination="QHN-nZ-kbB" eventType="valueChanged" id="yUy-FA-gYY"/>
|
||||
</connections>
|
||||
</switch>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" translatesAutoresizingMaskIntoConstraints="NO" id="KV2-tN-Aff">
|
||||
<rect key="frame" x="20" y="37" width="280" height="29"/>
|
||||
<segments>
|
||||
<segment title="Slide In"/>
|
||||
<segment title="Slide Out"/>
|
||||
<segment title="In + Out"/>
|
||||
<segment title="Dissolve"/>
|
||||
</segments>
|
||||
<connections>
|
||||
<action selector="changeSegment:" destination="QHN-nZ-kbB" eventType="valueChanged" id="xYG-CU-6tx"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="KV2-tN-Aff" firstAttribute="leading" secondItem="DMn-tw-NTB" secondAttribute="leading" constant="20" id="0Xw-7D-HJS"/>
|
||||
@@ -263,14 +264,14 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="961.875" y="8.4507042253521121"/>
|
||||
</scene>
|
||||
<!--Table View Controller-->
|
||||
<!--Side Menu Table View-->
|
||||
<scene sceneID="L2w-o7-jEN">
|
||||
<objects>
|
||||
<tableViewController id="V6g-oO-Tbm" sceneMemberID="viewController">
|
||||
<tableViewController id="V6g-oO-Tbm" customClass="SideMenuTableView" customModule="SideMenu_Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<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.25134698280000001" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" 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">
|
||||
@@ -395,14 +396,14 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="961.875" y="698.23943661971828"/>
|
||||
</scene>
|
||||
<!--Table View Controller-->
|
||||
<!--Side Menu Table View-->
|
||||
<scene sceneID="l9t-dY-QwR">
|
||||
<objects>
|
||||
<tableViewController id="Ol4-YR-KUL" sceneMemberID="viewController">
|
||||
<tableViewController id="Ol4-YR-KUL" customClass="SideMenuTableView" customModule="SideMenu_Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<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.25134698275862066" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" 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"/>
|
||||
|
||||
@@ -28,7 +28,7 @@ class MainViewController: UIViewController {
|
||||
// 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)
|
||||
@@ -51,7 +51,7 @@ class MainViewController: UIViewController {
|
||||
|
||||
darknessSlider.value = Float(SideMenuManager.menuAnimationFadeStrength)
|
||||
shadowOpacitySlider.value = Float(SideMenuManager.menuShadowOpacity)
|
||||
shrinkFactorSlider.value = Float(SideMenuManager.menuAnimationShrinkStrength)
|
||||
shrinkFactorSlider.value = Float(SideMenuManager.menuAnimationTransformScaleFactor)
|
||||
screenWidthSlider.value = Float(SideMenuManager.menuWidth / view.frame.width)
|
||||
blackOutStatusBar.on = SideMenuManager.menuFadeStatusBar
|
||||
}
|
||||
@@ -59,7 +59,7 @@ class MainViewController: UIViewController {
|
||||
@IBAction private func changeSegment(segmentControl: UISegmentedControl) {
|
||||
switch segmentControl {
|
||||
case presentModeSegmentedControl:
|
||||
let modes:[SideMenuManager.MenuPresentMode] = [.MenuSlideIn, .ViewSlideOut, .MenuDissolveIn]
|
||||
let modes:[SideMenuManager.MenuPresentMode] = [.MenuSlideIn, .ViewSlideOut, .ViewSlideInOut, .MenuDissolveIn]
|
||||
SideMenuManager.menuPresentMode = modes[segmentControl.selectedSegmentIndex]
|
||||
case blurSegmentControl:
|
||||
if segmentControl.selectedSegmentIndex == 0 {
|
||||
@@ -79,7 +79,7 @@ class MainViewController: UIViewController {
|
||||
case shadowOpacitySlider:
|
||||
SideMenuManager.menuShadowOpacity = slider.value
|
||||
case shrinkFactorSlider:
|
||||
SideMenuManager.menuAnimationShrinkStrength = CGFloat(slider.value)
|
||||
SideMenuManager.menuAnimationTransformScaleFactor = CGFloat(slider.value)
|
||||
case screenWidthSlider:
|
||||
SideMenuManager.menuWidth = view.frame.width * CGFloat(slider.value)
|
||||
default: break;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// SideMenuTableView.swift
|
||||
// SideMenu
|
||||
//
|
||||
// Created by Jon Kent on 4/5/16.
|
||||
// Copyright © 2016 CocoaPods. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SideMenu
|
||||
|
||||
class SideMenuTableView: UITableViewController {
|
||||
|
||||
override func viewWillAppear(animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
// this will be non-nil if a blur effect is applied
|
||||
guard tableView.backgroundView == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
// Set up a cool background image for demo purposes
|
||||
let imageView = UIImageView(image: UIImage(named: "saturn"))
|
||||
imageView.contentMode = .ScaleAspectFit
|
||||
imageView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.2)
|
||||
tableView.backgroundView = imageView
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,36 +21,101 @@ public class SideMenuManager {
|
||||
public enum MenuPresentMode {
|
||||
case MenuSlideIn
|
||||
case ViewSlideOut
|
||||
case ViewSlideInOut
|
||||
case MenuDissolveIn
|
||||
}
|
||||
|
||||
private static var originalLeftMenuBackgroundColor: UIColor?
|
||||
private static var originalRightMenuBackgroundColor: UIColor?
|
||||
|
||||
public static var menuPresentMode:MenuPresentMode = .ViewSlideOut
|
||||
// Bounds which has been allocated for the app on the whole device screen
|
||||
internal static var appScreenRect: CGRect {
|
||||
let appWindowRect = UIApplication.sharedApplication().keyWindow?.bounds ?? UIWindow().bounds
|
||||
return appWindowRect
|
||||
}
|
||||
|
||||
/**
|
||||
The presentation mode of the menu.
|
||||
|
||||
There are four modes in MenuPresentMode:
|
||||
- MenuSlideIn: Menu slides in over of the existing view.
|
||||
- ViewSlideOut: The existing view slides out to reveal the menu.
|
||||
- ViewSlideInOut: The existing view slides out while the menu slides in.
|
||||
- MenuDissolveIn: The menu dissolves in over the existing view controller.
|
||||
*/
|
||||
public static var menuPresentMode: MenuPresentMode = .ViewSlideOut
|
||||
|
||||
/// Prevents the same view controller (or a view controller of the same class) from being pushed more than once. Defaults to true.
|
||||
public static var menuAllowPushOfSameClassTwice = true
|
||||
|
||||
/// Pops to any view controller already in the navigation stack instead of the view controller being pushed if they share the same class. Defaults to false.
|
||||
public static var menuAllowPopIfPossible = false
|
||||
public static var menuWidth: CGFloat = max(round(min(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) * 0.75), 240)
|
||||
|
||||
/// Width of the menu when presented on screen, showing the existing view controller in the remaining space. Default is 75% of the screen width.
|
||||
public static var menuWidth: CGFloat = max(round(min((appScreenRect.width), (appScreenRect.height)) * 0.75), 240)
|
||||
|
||||
/// Duration of the animation when the menu is presented without gestures. Default is 0.35 seconds.
|
||||
public static var menuAnimationPresentDuration = 0.35
|
||||
|
||||
/// Duration of the animation when the menu is dismissed without gestures. Default is 0.35 seconds.
|
||||
public static var menuAnimationDismissDuration = 0.35
|
||||
|
||||
/// Amount to fade the existing view controller when the menu is presented. Default is 0 for no fade. Set to 1 to fade completely.
|
||||
public static var menuAnimationFadeStrength: CGFloat = 0
|
||||
public static var menuAnimationShrinkStrength: CGFloat = 1
|
||||
|
||||
/// The amount to scale the existing view controller or the menu view controller depending on the `menuPresentMode`. Default is 1 for no scaling. Less than 1 will shrink, greater than 1 will grow.
|
||||
public static var menuAnimationTransformScaleFactor: CGFloat = 1
|
||||
|
||||
/// The background color behind menu animations. Depending on the animation settings this may not be visible. If `menuFadeStatusBar` is true, this color is used to fade it. Default is black.
|
||||
public static var menuAnimationBackgroundColor: UIColor?
|
||||
|
||||
/// The shadow opacity around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is 0.5 for 50% opacity.
|
||||
public static var menuShadowOpacity: Float = 0.5
|
||||
|
||||
/// The shadow color around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is black.
|
||||
public static var menuShadowColor = UIColor.blackColor()
|
||||
|
||||
/// The radius of the shadow around the menu view controller or existing view controller depending on the `menuPresentMode`. Default is 5.
|
||||
public static var menuShadowRadius: CGFloat = 5
|
||||
|
||||
/// The left menu swipe to dismiss gesture.
|
||||
public static weak var menuLeftSwipeToDismissGesture: UIPanGestureRecognizer?
|
||||
|
||||
/// The right menu swipe to dismiss gesture.
|
||||
public static weak var menuRightSwipeToDismissGesture: UIPanGestureRecognizer?
|
||||
|
||||
/// The strength of the parallax effect on the existing view controller. Does not apply to `menuPresentMode` when set to `ViewSlideOut`. Default is 0.
|
||||
public static var menuParallaxStrength: Int = 0
|
||||
|
||||
/// Draws the `menuAnimationBackgroundColor` behind the status bar. Default is true.
|
||||
public static var menuFadeStatusBar = true
|
||||
|
||||
// Note: if you want cells in a UITableViewController menu to look good, make them a subclass of UITableViewVibrantCell!
|
||||
/// - Warning: Deprecated. Use `menuAnimationTransformScaleFactor` instead.
|
||||
@available(*, deprecated, renamed="menuAnimationTransformScaleFactor")
|
||||
public static var menuAnimationShrinkStrength: CGFloat {
|
||||
get {
|
||||
return menuAnimationTransformScaleFactor
|
||||
}
|
||||
set {
|
||||
menuAnimationTransformScaleFactor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// prevent instantiation
|
||||
private init() {}
|
||||
|
||||
/**
|
||||
The blur effect style of the menu if the menu's root view controller is a UITableViewController or UICollectionViewController.
|
||||
|
||||
- Note: If you want cells in a UITableViewController menu to show vibrancy, make them a subclass of UITableViewVibrantCell.
|
||||
*/
|
||||
public static var menuBlurEffectStyle: UIBlurEffectStyle? {
|
||||
didSet {
|
||||
updateMenuBlurIfNecessary()
|
||||
}
|
||||
}
|
||||
|
||||
/// The left menu.
|
||||
public static var menuLeftNavigationController: UISideMenuNavigationController? {
|
||||
willSet {
|
||||
if menuLeftNavigationController != nil {
|
||||
@@ -63,16 +128,20 @@ public class SideMenuManager {
|
||||
didSet {
|
||||
if let menuLeftNavigationController = menuLeftNavigationController {
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:"handleHideMenuPan:")
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
|
||||
menuLeftNavigationController.view.addGestureRecognizer(exitPanGesture)
|
||||
menuLeftNavigationController.transitioningDelegate = SideMenuTransition.singleton
|
||||
menuLeftNavigationController.modalPresentationStyle = .OverFullScreen
|
||||
if !menuLeftNavigationController.leftSide {
|
||||
menuLeftNavigationController.leftSide = true
|
||||
}
|
||||
menuLeftSwipeToDismissGesture = exitPanGesture
|
||||
updateMenuBlurIfNecessary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The right menu.
|
||||
public static var menuRightNavigationController: UISideMenuNavigationController? {
|
||||
willSet {
|
||||
if menuRightNavigationController != nil {
|
||||
@@ -85,10 +154,13 @@ public class SideMenuManager {
|
||||
didSet {
|
||||
if let menuRightNavigationController = menuRightNavigationController {
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:"handleHideMenuPan:")
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
|
||||
menuRightNavigationController.view.addGestureRecognizer(exitPanGesture)
|
||||
menuRightNavigationController.transitioningDelegate = SideMenuTransition.singleton
|
||||
menuRightNavigationController.modalPresentationStyle = .OverFullScreen
|
||||
if menuRightNavigationController.leftSide {
|
||||
menuRightNavigationController.leftSide = false
|
||||
}
|
||||
menuRightSwipeToDismissGesture = exitPanGesture
|
||||
updateMenuBlurIfNecessary()
|
||||
}
|
||||
@@ -155,13 +227,21 @@ public class SideMenuManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Adds screen edge gestures to a view to present a menu.
|
||||
|
||||
- Parameter toView: The view to add gestures to.
|
||||
- Parameter forMenu: The menu (left or right) you want to add a gesture for. If unspecified, gestures will be added for both sides.
|
||||
|
||||
- Returns: The array of screen edge gestures added to `toView`.
|
||||
*/
|
||||
public class func menuAddScreenEdgePanGesturesToPresent(toView toView: UIView, forMenu:UIRectEdge? = nil) -> [UIScreenEdgePanGestureRecognizer] {
|
||||
|
||||
var array = [UIScreenEdgePanGestureRecognizer]()
|
||||
|
||||
if forMenu != .Right {
|
||||
let leftScreenEdgeGestureRecognizer = UIScreenEdgePanGestureRecognizer()
|
||||
leftScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:"handlePresentMenuPan:")
|
||||
leftScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuLeftScreenEdge(_:)))
|
||||
leftScreenEdgeGestureRecognizer.edges = .Left
|
||||
leftScreenEdgeGestureRecognizer.cancelsTouchesInView = true
|
||||
toView.addGestureRecognizer(leftScreenEdgeGestureRecognizer)
|
||||
@@ -170,7 +250,7 @@ public class SideMenuManager {
|
||||
|
||||
if forMenu != .Left {
|
||||
let rightScreenEdgeGestureRecognizer = UIScreenEdgePanGestureRecognizer()
|
||||
rightScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:"handlePresentMenuPan:")
|
||||
rightScreenEdgeGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuRightScreenEdge(_:)))
|
||||
rightScreenEdgeGestureRecognizer.edges = .Right
|
||||
rightScreenEdgeGestureRecognizer.cancelsTouchesInView = true
|
||||
toView.addGestureRecognizer(rightScreenEdgeGestureRecognizer)
|
||||
@@ -180,9 +260,16 @@ public class SideMenuManager {
|
||||
return array
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a pan edge gesture to a view to present menus.
|
||||
|
||||
- Parameter toView: The view to add a pan gesture to.
|
||||
|
||||
- Returns: The pan gesture added to `toView`.
|
||||
*/
|
||||
public class func menuAddPanGestureToPresent(toView toView: UIView) -> UIPanGestureRecognizer {
|
||||
let panGestureRecognizer = UIPanGestureRecognizer()
|
||||
panGestureRecognizer.addTarget(SideMenuTransition.self, action:"handlePresentMenuPan:")
|
||||
panGestureRecognizer.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handlePresentMenuPan(_:)))
|
||||
toView.addGestureRecognizer(panGestureRecognizer)
|
||||
|
||||
return panGestureRecognizer
|
||||
|
||||
@@ -13,6 +13,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
private var presenting = false
|
||||
private var interactive = false
|
||||
private static weak var originalSuperview: UIView?
|
||||
private static var switchMenus = false
|
||||
|
||||
internal static let singleton = SideMenuTransition()
|
||||
internal static var presentDirection: UIRectEdge = .Left;
|
||||
@@ -46,62 +47,75 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
return viewController
|
||||
}
|
||||
|
||||
class func handlePresentMenuLeftScreenEdge(edge: UIScreenEdgePanGestureRecognizer) {
|
||||
SideMenuTransition.presentDirection = .Left
|
||||
handlePresentMenuPan(edge)
|
||||
}
|
||||
|
||||
class func handlePresentMenuRightScreenEdge(edge: UIScreenEdgePanGestureRecognizer) {
|
||||
SideMenuTransition.presentDirection = .Right
|
||||
handlePresentMenuPan(edge)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
guard let view = viewControllerForPresentedMenu != nil ? viewControllerForPresentedMenu?.view : pan.view else {
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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()
|
||||
if !(pan is UIScreenEdgePanGestureRecognizer) {
|
||||
SideMenuTransition.presentDirection = translation.x > 0 ? .Left : .Right
|
||||
}
|
||||
|
||||
if let menuViewController = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController : SideMenuManager.menuRightNavigationController,
|
||||
visibleViewController = visibleViewController {
|
||||
singleton.interactive = true
|
||||
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
|
||||
switchMenus = true
|
||||
singleton.cancelInteractiveTransition()
|
||||
} else if distance < 0 && SideMenuTransition.presentDirection == .Left && SideMenuManager.menuRightNavigationController != nil {
|
||||
SideMenuTransition.presentDirection = .Right
|
||||
switchMenus = true
|
||||
singleton.cancelInteractiveTransition()
|
||||
} 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 {
|
||||
// bug workaround: animation briefly resets after call to finishInteractiveTransition() but before animateTransition completion is called.
|
||||
if NSProcessInfo().operatingSystemVersion.majorVersion == 8 && singleton.percentComplete > 1 - CGFloat(FLT_EPSILON) {
|
||||
singleton.updateInteractiveTransition(0.9999)
|
||||
}
|
||||
singleton.finishInteractiveTransition()
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,9 +136,12 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
singleton.interactive = false
|
||||
let velocity = pan.velocityInView(pan.view!).x * direction
|
||||
if velocity >= 100 || velocity >= -50 && distance >= 0.5 {
|
||||
// bug workaround: animation briefly resets after call to finishInteractiveTransition() but before animateTransition completion is called.
|
||||
if NSProcessInfo().operatingSystemVersion.majorVersion == 8 && singleton.percentComplete > 1 - CGFloat(FLT_EPSILON) {
|
||||
singleton.updateInteractiveTransition(0.9999)
|
||||
}
|
||||
singleton.finishInteractiveTransition()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
@@ -135,6 +152,8 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
}
|
||||
|
||||
internal class func hideMenuStart() {
|
||||
NSNotificationCenter.defaultCenter().removeObserver(SideMenuTransition.singleton)
|
||||
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController!.view : SideMenuManager.menuRightNavigationController!.view
|
||||
menuView.transform = CGAffineTransformIdentity
|
||||
@@ -153,7 +172,12 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
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)
|
||||
menuView.transform = CGAffineTransformMakeScale(SideMenuManager.menuAnimationTransformScaleFactor, SideMenuManager.menuAnimationTransformScaleFactor)
|
||||
|
||||
case .ViewSlideInOut:
|
||||
menuView.alpha = 1
|
||||
menuView.frame.origin.x = SideMenuTransition.presentDirection == .Left ? -menuView.frame.width : mainViewController.view.frame.width
|
||||
mainViewController.view.frame.origin.x = 0
|
||||
|
||||
case .MenuSlideIn:
|
||||
menuView.alpha = 1
|
||||
@@ -174,52 +198,66 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
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) {
|
||||
internal class func presentMenuStart(forSize size: CGSize = SideMenuManager.appScreenRect.size) {
|
||||
guard let menuView = SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController?.view : SideMenuManager.menuRightNavigationController?.view else {
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
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 {
|
||||
|
||||
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
|
||||
}
|
||||
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 .ViewSlideInOut:
|
||||
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)
|
||||
let direction:CGFloat = SideMenuTransition.presentDirection == .Left ? 1 : -1
|
||||
mainViewController.view.frame.origin.x = direction * (menuView.frame.width)
|
||||
mainViewController.view.transform = CGAffineTransformMakeScale(SideMenuManager.menuAnimationTransformScaleFactor, SideMenuManager.menuAnimationTransformScaleFactor)
|
||||
mainViewController.view.alpha = 1 - SideMenuManager.menuAnimationFadeStrength
|
||||
|
||||
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.menuAnimationTransformScaleFactor, SideMenuManager.menuAnimationTransformScaleFactor)
|
||||
mainViewController.view.alpha = 1 - SideMenuManager.menuAnimationFadeStrength
|
||||
}
|
||||
}
|
||||
|
||||
internal class func presentMenuComplete() {
|
||||
NSNotificationCenter.defaultCenter().addObserver(SideMenuTransition.singleton, selector:#selector(SideMenuTransition.applicationDidEnterBackgroundNotification), name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
|
||||
if SideMenuManager.menuParallaxStrength != 0 {
|
||||
let horizontal = UIInterpolatingMotionEffect(keyPath: "center.x", type: .TiltAlongHorizontalAxis)
|
||||
horizontal.minimumRelativeValue = -SideMenuManager.menuParallaxStrength
|
||||
@@ -245,8 +283,6 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
// 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 {
|
||||
@@ -269,9 +305,9 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
let tapView = UIView()
|
||||
tapView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
|
||||
let exitPanGesture = UIPanGestureRecognizer()
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:"handleHideMenuPan:")
|
||||
exitPanGesture.addTarget(SideMenuTransition.self, action:#selector(SideMenuTransition.handleHideMenuPan(_:)))
|
||||
let exitTapGesture = UITapGestureRecognizer()
|
||||
exitTapGesture.addTarget(SideMenuTransition.self, action: "handleHideMenuTap:")
|
||||
exitTapGesture.addTarget(SideMenuTransition.self, action: #selector(SideMenuTransition.handleHideMenuTap(_:)))
|
||||
tapView.addGestureRecognizer(exitPanGesture)
|
||||
tapView.addGestureRecognizer(exitTapGesture)
|
||||
SideMenuTransition.tapView = tapView
|
||||
@@ -284,7 +320,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
container.addSubview(menuView)
|
||||
container.addSubview(topView)
|
||||
topView.addSubview(tapView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
|
||||
container.addSubview(topView)
|
||||
container.addSubview(tapView)
|
||||
container.addSubview(menuView)
|
||||
@@ -303,9 +339,6 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
}
|
||||
|
||||
SideMenuTransition.hideMenuStart() // offstage for interactive
|
||||
|
||||
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||
NSNotificationCenter.defaultCenter().addObserver(SideMenuTransition.singleton, selector:"applicationDidEnterBackgroundNotification", name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
}
|
||||
|
||||
// perform the animation!
|
||||
@@ -319,34 +352,44 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
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() {
|
||||
let viewControllerForPresentedMenu = SideMenuTransition.viewControllerForPresentedMenu
|
||||
|
||||
if self.presenting {
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
} else {
|
||||
SideMenuTransition.presentMenuComplete()
|
||||
}
|
||||
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()
|
||||
|
||||
if SideMenuTransition.switchMenus {
|
||||
SideMenuTransition.switchMenus = false
|
||||
viewControllerForPresentedMenu?.presentViewController(SideMenuTransition.presentDirection == .Left ? SideMenuManager.menuLeftNavigationController! : SideMenuManager.menuRightNavigationController!, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if self.presenting {
|
||||
SideMenuTransition.presentMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
container.addSubview(topView)
|
||||
case .MenuSlideIn, .MenuDissolveIn, .ViewSlideInOut:
|
||||
container.insertSubview(topView, atIndex: 0)
|
||||
}
|
||||
if let statusBarView = SideMenuTransition.statusBarView {
|
||||
container.bringSubviewToFront(statusBarView)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
SideMenuTransition.hideMenuComplete()
|
||||
transitionContext.completeTransition(true)
|
||||
menuView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +400,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
|
||||
// MARK: UIViewControllerTransitioningDelegate protocol methods
|
||||
|
||||
// return the animataor when presenting a viewcontroller
|
||||
// return the animator 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
|
||||
|
||||
@@ -18,6 +18,7 @@ public class UISideMenuNavigationController: UINavigationController {
|
||||
modalPresentationStyle = .OverFullScreen
|
||||
}
|
||||
|
||||
/// Whether the menu appears on the right or left side of the screen. Right is the default.
|
||||
@IBInspectable public var leftSide:Bool = false {
|
||||
didSet {
|
||||
if isViewLoaded() { // suppress warnings
|
||||
@@ -60,7 +61,7 @@ public class UISideMenuNavigationController: UINavigationController {
|
||||
if !isBeingDismissed() {
|
||||
if let mainView = presentingViewController?.view {
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
case .ViewSlideOut:
|
||||
case .ViewSlideOut, .ViewSlideInOut:
|
||||
mainView.superview?.insertSubview(view, belowSubview: mainView)
|
||||
case .MenuSlideIn, .MenuDissolveIn:
|
||||
mainView.superview?.insertSubview(view, aboveSubview: SideMenuTransition.tapView)
|
||||
|
||||
@@ -3,21 +3,30 @@
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
|
||||
### If you like SideMenu, give it a ★ at the top right of this page.
|
||||
## Shameless Requests First
|
||||
**1. ### If you like SideMenu, give it a ★ at the top right of its [GitHub](https://github.com/jonkykong/SideMenu) page.**
|
||||
|
||||
**2. I need an invite to Dribbble to share SideMenu. Invite me: https://dribbble.com/jonkykong**
|
||||
|
||||
## Overview
|
||||
|
||||
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.
|
||||
* **It can be implemented in storyboard without a single line of [code](#code-less-storyboard-implementation).**
|
||||
* Four standard animation styles to choose from (even parallax if you want to get weird).
|
||||
* Highly customizable without needing to write tons of custom code.
|
||||
* Supports continuous swiping between side menus on boths sides in a single gesture.
|
||||
* Global menu configuration. Set-up once and be done for all screens.
|
||||
* 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!
|
||||
Check out the example project or this [interactive demo](https://appetize.io/app/64a9v3e6b8c6f53zvn5pnny80m) to see it in action!
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Requirements
|
||||
- [x] iOS 8 or higher
|
||||
* iOS 8 or higher
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -95,7 +104,7 @@ menuWidth: CGFloat = max(round(min(UIScreen.mainScreen().bounds.width, UIScreen.
|
||||
menuAnimationPresentDuration = 0.35
|
||||
menuAnimationDismissDuration = 0.35
|
||||
menuAnimationFadeStrength: CGFloat = 0
|
||||
menuAnimationShrinkStrength: CGFloat = 1
|
||||
menuAnimationTransformScaleFactor: CGFloat = 1
|
||||
menuAnimationBackgroundColor: UIColor? = nil
|
||||
menuShadowOpacity: Float = 0.5
|
||||
menuShadowColor = UIColor.blackColor()
|
||||
@@ -114,6 +123,13 @@ 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 the UI. See [radar 21961293](http://www.openradar.me/21961293) for more information.
|
||||
|
||||
## About Me
|
||||
My name is Jon Kent and I'm a freelance iOS designer, developer, and mobile strategist. I love coffee and play the drums. **Hire me!**
|
||||
|
||||
🌎 Web: [http://jonkent.me](http://jonkent.me)
|
||||
|
||||
✉️ Email: [contact@jonkent.me](mailto:contact@jonkent.me)
|
||||
|
||||
## License
|
||||
|
||||
SideMenu is available under the MIT license. See the LICENSE file for more info.
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SideMenu"
|
||||
s.version = "1.0.0"
|
||||
s.summary = "Simple side menu control in Swift inspired by Facebook. Right and Left sides. No coding required."
|
||||
s.version = "1.1.6"
|
||||
s.summary = "Simple side menu control for iOS 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.screenshot = "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Preview.gif"
|
||||
s.screenshots = [ "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/SlideOut.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/SlideIn.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Dissolve.gif", "https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/InOut.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: 764 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 438 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 8.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 663 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 605 KiB |
Reference in New Issue
Block a user