Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 07f6dff8e8 | |||
| a195757c1d | |||
| 68648ef3f1 | |||
| fec44d0cc2 | |||
| 4da251f6ea | |||
| ddbc431d45 | |||
| 405a3ea56d | |||
| 031e3bcfba | |||
| c08c9a92ec | |||
| f980f558b4 | |||
| b183c95efd | |||
| 110eca43d3 | |||
| 8598050032 | |||
| 08e482c412 | |||
| 8b833b9044 | |||
| b1f51cdcca | |||
| 6a33fea711 | |||
| 2e5b209a0c | |||
| 5463a48207 | |||
| ab5d7a17d6 | |||
| 339468f95d | |||
| 933b9e93f3 | |||
| ab420fa769 |
@@ -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,6 +21,7 @@ public class SideMenuManager {
|
||||
public enum MenuPresentMode {
|
||||
case MenuSlideIn
|
||||
case ViewSlideOut
|
||||
case ViewSlideInOut
|
||||
case MenuDissolveIn
|
||||
}
|
||||
|
||||
@@ -34,7 +35,7 @@ public class SideMenuManager {
|
||||
public static var menuAnimationPresentDuration = 0.35
|
||||
public static var menuAnimationDismissDuration = 0.35
|
||||
public static var menuAnimationFadeStrength: CGFloat = 0
|
||||
public static var menuAnimationShrinkStrength: CGFloat = 1
|
||||
public static var menuAnimationTransformScaleFactor: CGFloat = 1
|
||||
public static var menuAnimationBackgroundColor: UIColor?
|
||||
public static var menuShadowOpacity: Float = 0.5
|
||||
public static var menuShadowColor = UIColor.blackColor()
|
||||
@@ -44,6 +45,19 @@ public class SideMenuManager {
|
||||
public static var menuParallaxStrength: Int = 0
|
||||
public static var menuFadeStatusBar = true
|
||||
|
||||
@available(*, deprecated, renamed="menuAnimationTransformScaleFactor")
|
||||
public static var menuAnimationShrinkStrength: CGFloat {
|
||||
get {
|
||||
return menuAnimationTransformScaleFactor
|
||||
}
|
||||
set {
|
||||
menuAnimationTransformScaleFactor = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// prevent instantiation
|
||||
private init() {}
|
||||
|
||||
// Note: if you want cells in a UITableViewController menu to look good, make them a subclass of UITableViewVibrantCell!
|
||||
public static var menuBlurEffectStyle: UIBlurEffectStyle? {
|
||||
didSet {
|
||||
@@ -63,7 +77,7 @@ 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
|
||||
@@ -85,7 +99,7 @@ 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
|
||||
@@ -159,18 +173,18 @@ public class SideMenuManager {
|
||||
|
||||
var array = [UIScreenEdgePanGestureRecognizer]()
|
||||
|
||||
if forMenu != .Right {
|
||||
if forMenu != .Left {
|
||||
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)
|
||||
array.append(leftScreenEdgeGestureRecognizer)
|
||||
}
|
||||
|
||||
if forMenu != .Left {
|
||||
if forMenu != .Right {
|
||||
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)
|
||||
@@ -182,7 +196,7 @@ public class SideMenuManager {
|
||||
|
||||
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,71 @@ 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 {
|
||||
singleton.finishInteractiveTransition()
|
||||
} else {
|
||||
singleton.cancelInteractiveTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +165,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
|
||||
@@ -204,6 +219,17 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
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
|
||||
@@ -211,14 +237,14 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
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.transform = CGAffineTransformMakeScale(SideMenuManager.menuAnimationTransformScaleFactor, SideMenuManager.menuAnimationTransformScaleFactor)
|
||||
mainViewController.view.alpha = 1 - SideMenuManager.menuAnimationFadeStrength
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class func presentMenuComplete() {
|
||||
NSNotificationCenter.defaultCenter().addObserver(SideMenuTransition.singleton, selector:"applicationDidEnterBackgroundNotification", name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
NSNotificationCenter.defaultCenter().addObserver(SideMenuTransition.singleton, selector:#selector(SideMenuTransition.applicationDidEnterBackgroundNotification), name: UIApplicationDidEnterBackgroundNotification, object: nil)
|
||||
|
||||
let mainViewController = SideMenuTransition.viewControllerForPresentedMenu!
|
||||
switch SideMenuManager.menuPresentMode {
|
||||
@@ -236,7 +262,7 @@ internal class SideMenuTransition: UIPercentDrivenInteractiveTransition, UIViewC
|
||||
group.motionEffects = [horizontal, vertical]
|
||||
mainViewController.view.addMotionEffect(group)
|
||||
}
|
||||
case .ViewSlideOut: break;
|
||||
case .ViewSlideOut, .ViewSlideInOut: break;
|
||||
}
|
||||
if let topNavigationController = mainViewController as? UINavigationController {
|
||||
topNavigationController.interactivePopGestureRecognizer!.enabled = false
|
||||
@@ -248,8 +274,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 {
|
||||
@@ -272,9 +296,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
|
||||
@@ -287,7 +311,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)
|
||||
@@ -319,36 +343,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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,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,24 @@
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
[](http://cocoapods.org/pods/SideMenu)
|
||||
|
||||
### If you like SideMenu, give it a ★ at the top right of its [GitHub](https://github.com/jonkykong/SideMenu) page.
|
||||
### 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.
|
||||
* **It can be implemented in storyboard without a single line of code.**
|
||||
* Three standard animation styles to choose from.
|
||||
* Highly customizable without needing to write tons of custom code.
|
||||
* Supports continuous swiping between each side menu in a single gesture.
|
||||
* Menus can be presented and dismissed the same as any other View Controller since this control uses custom transitions.
|
||||
- [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/5y7n2bk8f6jz58h92871udem54) 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
|
||||
* iOS 8 or higher
|
||||
- [x] iOS 8 or higher
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -95,7 +98,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()
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SideMenu"
|
||||
s.version = "1.0.3"
|
||||
s.summary = "Simple side menu control in Swift inspired by Facebook. Right and Left sides. No coding required."
|
||||
s.version = "1.1.2"
|
||||
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