Compare commits

...

118 Commits

Author SHA1 Message Date
jonkykong 37071b5d06 Updated podspec 2019-09-24 22:38:42 -07:00
jonkykong 607260ac2e Fix for view controller views now being clipped causing shadows not to work. 2019-09-24 22:38:27 -07:00
jonkykong 9f3759c90c Updated podspec 2019-09-24 03:07:11 -07:00
jonkykong c346f2e0db Minor refactor 2019-09-24 03:06:02 -07:00
jonkykong 6c72727408 iOS 13 support 2019-09-24 03:05:48 -07:00
jonkykong b649404a7e Refactor 2019-09-21 23:34:26 -07:00
jonkykong 3272a0f63e Refactor 2019-09-21 18:03:30 -07:00
jonkykong 70fa815037 Refactor 2019-09-21 18:03:09 -07:00
jonkykong 794767455a Updated podspec 2019-09-19 00:26:03 -07:00
Matteo Piccina 7359ee6801 Update Package.swift 2019-09-15 15:10:29 +02:00
jonkykong 0b62749bff Updated podspec 2019-09-13 01:49:20 -07:00
Jon Kent 7179713c18 Update README.md 2019-09-13 01:37:51 -07:00
Jon Kent 60f6f204c1 Update README.md 2019-09-13 01:27:26 -07:00
jonkykong 98c5b2b3e3 Updated podspec 2019-09-13 01:12:00 -07:00
jonkykong e8882a952d Reverting swift 4.2 changes. 2019-09-13 01:11:46 -07:00
jonkykong efc2e11fb2 Refactor 2019-09-13 01:10:51 -07:00
jonkykong 36662fa0f3 Merge branch 'pr/540' into 6.2.9
* pr/540:
  Fix File Reference to SideMenu.h
2019-09-13 00:58:08 -07:00
Alex Leeds dce89eb448 Fix File Reference to SideMenu.h 2019-09-11 10:41:21 -04:00
Rafael Francisco 32f1101e86 Fixed notification names 2019-09-10 14:17:50 +01:00
Rafael Francisco d25de76a92 Added SwiftPM support 2019-09-06 15:24:53 +01:00
jonkykong 59faed8ef9 Update podspec 2019-09-06 03:02:08 -07:00
jonkykong 4f990e86a8 Fix and refactor 2019-09-06 03:01:51 -07:00
jonkykong 8200e0d49f correction 2019-09-06 00:09:05 -07:00
jonkykong 5bb2f86b0a Updated podspec 2019-09-06 00:05:52 -07:00
jonkykong c591059fbe Crash fix 2019-09-06 00:05:39 -07:00
jonkykong cf6ec23a7f File structure reorganization 2019-09-05 02:28:46 -07:00
jonkykong 21a7347079 Refactor 2019-09-05 02:18:08 -07:00
jonkykong fc593b0cb7 Cleanup 2019-09-05 02:13:13 -07:00
jonkykong 55bfef578c Cleanup 2019-09-05 02:07:49 -07:00
jonkykong 620b248799 Cleanup 2019-09-05 02:04:47 -07:00
jonkykong 279ba484d3 Fix build issues 2019-09-05 02:01:17 -07:00
jonkykong c46745cef8 Refactor 2019-09-04 23:42:02 -07:00
jonkykong 8cc163dc5f Updated podspec 2019-09-04 23:36:33 -07:00
jonkykong fae34995ab Refactoring 2019-09-04 23:31:08 -07:00
jonkykong 90878cc0d5 Updated podspec 2019-09-04 01:42:39 -07:00
jonkykong 3f78b9bb49 Refactor 2019-09-04 01:40:44 -07:00
Jon Kent 6f8f224e00 Update README.md 2019-08-28 17:28:58 -07:00
jonkykong bc37f1b9cb Updated podspec 2019-08-25 21:07:17 -07:00
jonkykong 8aff2b3627 Merge tag '6.2.3' into 6.2.4
* tag '6.2.3':
  Updated podspec
  Propagate configured onTopShadowOffset to layer
2019-08-25 21:06:55 -07:00
jonkykong 135a3d2a94 Updated podspec 2019-08-20 23:15:01 -07:00
Marius Rackwitz a10b94e351 Propagate configured onTopShadowOffset to layer 2019-08-20 12:50:25 +02:00
Artur Azarau e1bf7c4991 delegate was made public 2019-08-19 14:08:54 +03:00
jonkykong b19c93ff2c Updated podspec 2019-08-17 10:59:18 -07:00
jonkykong 3968686410 Storyboard fix 2019-08-17 10:59:04 -07:00
jonkykong 0a457b414e Updated podspec 2019-08-14 02:20:38 -07:00
jonkykong 5abf5ca740 Updated screenshot 2019-08-14 02:20:25 -07:00
jonkykong 498669bf58 Updated README 2019-08-14 02:16:18 -07:00
jonkykong 159c87871b Expanded renaming to include delegates 2019-08-14 02:16:02 -07:00
jonkykong 4c0733d82a Updated podspec 2019-08-14 01:24:08 -07:00
jonkykong c3671408da Renamed and deprecated UISideMenuNavigationController to SideMenuNavigationController 2019-08-14 01:23:55 -07:00
jonkykong 3268b15e54 Marked InitializableClass as internal 2019-08-14 01:23:08 -07:00
jonkykong 22a7723345 Updated podspec 2019-08-11 10:15:08 -07:00
jonkykong 423b56b9ac Fix for dismiss not working when menu is revealed interactively 2019-08-11 10:09:09 -07:00
Jon Kent 06fbf875d0 Update README.md 2019-08-11 01:07:55 -07:00
jonkykong 9d9c22c786 Updated tests 2019-08-11 01:06:29 -07:00
jonkykong de1b010ac1 Added shared scheme 2019-08-10 23:47:52 -07:00
jonkykong d061bd178d Updated circle config 2019-08-10 23:12:18 -07:00
jonkykong 93ddab1377 Updated circle config 2019-08-10 20:27:47 -07:00
jonkykong 60854beac1 Added basic support for CircleCI 2019-08-10 20:05:17 -07:00
jonkykong 2e8740a91e Update podspec 2019-08-07 01:39:23 -07:00
jonkykong b387ef2dd7 Merge branch 'pr/524' into 6.1.4
* pr/524:
  Refactor
  Added isHidden property for public usage
2019-08-07 01:38:41 -07:00
jonkykong 22596320a3 Refactor 2019-08-07 01:38:28 -07:00
jonkykong 9363b747d1 Push logic fix 2019-08-07 01:31:22 -07:00
Mykola Vaniurskyi baae6186d7 Added isHidden property for public usage 2019-08-06 16:10:20 +03:00
jonkykong c5f80f954c Updated podspec version 2019-08-05 00:30:31 -07:00
jonkykong 493fa9a7a1 Updated podspec for swift version 2019-08-05 00:29:25 -07:00
jonkykong 2de8d7f758 Minor refactoring 2019-08-02 03:12:04 -07:00
jonkykong 62a37e20d1 Merge branch 'master' into 6.1.2
* master:
  Update README.md
2019-07-31 00:39:12 -07:00
jonkykong 7a799b94a8 Updated podspec 2019-07-31 00:38:36 -07:00
jonkykong 3a01ab6398 Fix for programmatic dismissal of menu after being interactively exposed. 2019-07-31 00:37:57 -07:00
Jon Kent 5e4ab5e254 Update README.md 2019-07-29 15:34:58 -07:00
jonkykong 70715d6fa0 Updated podspec 2019-07-29 00:57:22 -07:00
jonkykong 411bd59493 Refactor 2019-07-29 00:56:05 -07:00
jonkykong 5e295d36eb Fix for gesture cancelation causing menu unresponsiveness 2019-07-29 00:53:21 -07:00
jonkykong 6aa68df4ce Update podspec 2019-07-28 23:05:46 -07:00
jonkykong 5c292125a6 Fix for tap gesture not working in landscape mode 2019-07-28 23:04:34 -07:00
jonkykong 48eb4a2e3a Fix for delegate not always being called 2019-07-28 23:04:18 -07:00
jonkykong 9503c814d6 README update 2019-07-28 23:03:59 -07:00
jonkykong 4dd4f54a8e Refactor + add support for tap gesture option 2019-07-28 23:03:41 -07:00
jonkykong 7429a42c26 Fix for landscape mode menu tap to dismiss 2019-07-28 16:05:49 -07:00
jonkykong df032e6072 Fix for updating UI in demo project 2019-07-28 16:05:23 -07:00
jonkykong 3a7c74e2e0 Fix for viewWillDisappear not being called 2019-07-27 03:28:14 -07:00
jonkykong 900926f268 Updated strings 2019-07-27 03:27:46 -07:00
jonkykong f5e585857c Updated documentation 2019-07-27 03:27:24 -07:00
Mikhail Apurin 1d96ef80b3 Unreliable dismissal by tap gesture 2019-07-25 16:50:11 +09:00
Jon Kent 452b354e19 Update README.md 2019-07-24 10:20:04 -07:00
jonkykong 78a3a66a69 Updated podspec 2019-07-23 01:41:18 -07:00
jonkykong 8fe0a23a38 Auto-assignment of leftSide property from SideMenuManager 2019-07-23 01:40:35 -07:00
jonkykong 3a873661c3 Refactor 2019-07-23 00:58:06 -07:00
jonkykong 89fc05a324 Example project fix 2019-07-23 00:55:16 -07:00
jonkykong 453e110246 Refactor 2019-07-23 00:55:02 -07:00
jonkykong b39142bc1a Updated podspec 2019-07-22 01:13:26 -07:00
jonkykong a6bd743e99 README correction 2019-07-22 01:13:15 -07:00
jonkykong 749588918c Logic correction 2019-07-22 01:13:02 -07:00
jonkykong f5b6615c72 Podspec update 2019-07-21 21:44:17 -07:00
jonkykong 8804675b80 Demo project correction 2019-07-21 21:43:42 -07:00
jonkykong b0a09a5b7d Fix for layout when menu not dismissed during presentation 2019-07-21 21:43:25 -07:00
jonkykong f1e4efeb46 Refactor 2019-07-21 21:43:07 -07:00
jonkykong aea7592d85 Scope change 2019-07-19 00:49:26 -07:00
jonkykong 87edaf1d32 Update podspec 2019-07-19 00:32:22 -07:00
jonkykong d14a8d66b3 Tighten up gesture logic 2019-07-19 00:30:01 -07:00
jonkykong 36e8131965 Layering fix 2019-07-19 00:14:57 -07:00
jonkykong 58318a638d Example project fix 2019-07-19 00:14:31 -07:00
jonkykong 06ea874cc6 Updated podspec 2019-07-18 00:16:50 -07:00
jonkykong fd8437b181 Cleaned up deprecations 2019-07-18 00:16:25 -07:00
Jon Kent 8c0d6b636f Update Deprecations.swift 2019-07-17 16:22:08 -07:00
jonkykong 44d1de7d48 Upped podspec 2019-07-17 09:44:50 -07:00
jonkykong 287434b008 Refactor 2019-07-17 09:44:33 -07:00
jonkykong c0ec53608f Fix for unresponsive presentation 2019-07-17 09:36:55 -07:00
jonkykong 54a9f3887d Fix for programmatic instantiation not calling setup() 2019-07-17 02:49:10 -07:00
jonkykong 82b3e95c29 Upped podspec 2019-07-16 02:38:34 -07:00
jonkykong 7ffe987e96 Fix to build all schemes 2019-07-16 02:38:22 -07:00
jonkykong 14ddcaa1cb Upped podspec 2019-07-16 02:28:05 -07:00
jonkykong e94153ce25 Crash fix 2019-07-16 02:25:40 -07:00
jonkykong b9a5ed0886 Refactor 2019-07-16 02:25:00 -07:00
Jon Kent b2c8bedaca Update README.md 2019-07-14 13:37:41 -07:00
Jon Kent e94de73713 Update README.md 2019-07-14 13:23:37 -07:00
Jon Kent b43f4d14f3 Update README.md 2019-07-14 13:22:05 -07:00
36 changed files with 1592 additions and 1050 deletions
+39
View File
@@ -0,0 +1,39 @@
# iOS CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/ios-migrating-from-1-2/ for more details
#
version: 2
jobs:
build:
# Specify the Xcode version to use
macos:
xcode: "10.3.0"
steps:
- checkout
# Install CocoaPods
- run:
name: Install CocoaPods
command: pod install
# Build the app and run tests
- run:
name: Build and run tests
command: fastlane scan
environment:
SCAN_DEVICE: iPhone Xʀ
SCAN_SCHEME: SideMenu Example
# Collect XML test results data to show in the UI,
# and save the same XML files under test-results folder
# in the Artifacts tab
- store_test_results:
path: test_output/report.xml
- store_artifacts:
path: /tmp/test-results
destination: scan-test-results
- store_artifacts:
path: ~/Library/Logs/scan
destination: scan-logs
+65 -65
View File
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="yAA-s6-Bam">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="yAA-s6-Bam">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -15,7 +13,7 @@
<objects>
<navigationController id="yAA-s6-Bam" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" id="Bue-4e-bCJ">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<gestureRecognizers/>
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -38,10 +36,10 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LFJ-SB-Zp9">
<rect key="frame" x="0.0" y="64" width="375" height="571"/>
<rect key="frame" x="0.0" y="44" width="375" height="591"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="iBe-qv-i0y">
<rect key="frame" x="20" y="20" width="335" height="675"/>
<rect key="frame" x="20" y="20" width="335" height="681"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Presentation Style" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Efp-5L-qft">
<rect key="frame" x="0.0" y="0.0" width="335" height="20.5"/>
@@ -50,7 +48,7 @@
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="KV2-tN-Aff">
<rect key="frame" x="0.0" y="28.5" width="335" height="29"/>
<rect key="frame" x="0.0" y="28.5" width="335" height="32"/>
<segments>
<segment title="Slide In"/>
<segment title="Slide Out"/>
@@ -62,19 +60,19 @@
</connections>
</segmentedControl>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wsl-iY-a5K">
<rect key="frame" x="0.0" y="64.5" width="335" height="4"/>
<rect key="frame" x="0.0" y="67.5" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="oRw-Gi-ezT"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Blur Style" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OHe-SA-S0e">
<rect key="frame" x="0.0" y="76.5" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="79.5" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" translatesAutoresizingMaskIntoConstraints="NO" id="owH-AA-wgw">
<rect key="frame" x="0.0" y="105" width="335" height="29"/>
<rect key="frame" x="0.0" y="108" width="335" height="32"/>
<segments>
<segment title="None"/>
<segment title="Dark"/>
@@ -86,121 +84,121 @@
</connections>
</segmentedControl>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="svy-p5-tiL">
<rect key="frame" x="0.0" y="141" width="335" height="4"/>
<rect key="frame" x="0.0" y="147" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="wra-S3-qWU"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Start Alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tRs-iN-9Ht">
<rect key="frame" x="0.0" y="153" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="159" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="pqT-4M-nw1">
<rect key="frame" x="-2" y="181.5" width="339" height="31"/>
<rect key="frame" x="-2" y="187.5" width="339" height="31"/>
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="changeControl:" destination="QHN-nZ-kbB" eventType="valueChanged" id="Rfw-ZT-ziI"/>
</connections>
</slider>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="r3M-VQ-eCj">
<rect key="frame" x="0.0" y="219.5" width="335" height="4"/>
<rect key="frame" x="0.0" y="225.5" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="RvV-Fo-ext"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Presenting End Alpha" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NmN-uG-ABp">
<rect key="frame" x="0.0" y="231.5" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="237.5" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="xlA-NK-mN4">
<rect key="frame" x="-2" y="260" width="339" height="31"/>
<rect key="frame" x="-2" y="266" width="339" height="31"/>
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="changeControl:" destination="QHN-nZ-kbB" eventType="valueChanged" id="ah6-OO-Zh9"/>
</connections>
</slider>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bjn-LU-15M">
<rect key="frame" x="0.0" y="298" width="335" height="4"/>
<rect key="frame" x="0.0" y="304" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="jLL-oP-eBj"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Shadow Opacity" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2QC-6F-Xpx">
<rect key="frame" x="0.0" y="310" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="316" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<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="-2" y="338.5" width="339" height="31"/>
<rect key="frame" x="-2" y="344.5" width="339" height="31"/>
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="changeControl:" destination="QHN-nZ-kbB" eventType="valueChanged" id="Vw7-lT-kal"/>
</connections>
</slider>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cKX-Y9-C8e">
<rect key="frame" x="0.0" y="376.5" width="335" height="4"/>
<rect key="frame" x="0.0" y="382.5" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="6m5-zX-BY6"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Screen Width" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Snj-Mg-6ww">
<rect key="frame" x="0.0" y="388.5" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="394.5" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="Cor-r1-osR">
<rect key="frame" x="-2" y="417" width="339" height="31"/>
<rect key="frame" x="-2" y="423" width="339" height="31"/>
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="changeControl:" destination="QHN-nZ-kbB" eventType="valueChanged" id="QfP-ZL-gGs"/>
</connections>
</slider>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="03z-3b-0TF">
<rect key="frame" x="0.0" y="455" width="335" height="4"/>
<rect key="frame" x="0.0" y="461" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="Kf2-9J-fIV"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Scale Factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tsg-30-YHs">
<rect key="frame" x="0.0" y="467" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="473" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<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="-2" y="495.5" width="339" height="31"/>
<rect key="frame" x="-2" y="501.5" width="339" height="31"/>
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="changeControl:" destination="QHN-nZ-kbB" eventType="valueChanged" id="lNd-9Z-lpP"/>
</connections>
</slider>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FrH-kR-j43">
<rect key="frame" x="0.0" y="533.5" width="335" height="4"/>
<rect key="frame" x="0.0" y="539.5" width="335" height="4"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="9kG-hd-eZS"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Presenting Scale Factor" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j7p-7c-wlI">
<rect key="frame" x="0.0" y="545.5" width="335" height="20.5"/>
<rect key="frame" x="0.0" y="551.5" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.001" minValue="0.001" maxValue="2" translatesAutoresizingMaskIntoConstraints="NO" id="Oso-tQ-0MO">
<rect key="frame" x="-2" y="574" width="339" height="31"/>
<rect key="frame" x="-2" y="580" width="339" height="31"/>
<color key="thumbTintColor" red="0.25098040700000002" green="0.0" blue="0.50196081400000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="changeControl:" destination="QHN-nZ-kbB" eventType="valueChanged" id="TuI-Au-hWY"/>
</connections>
</slider>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DMn-tw-NTB">
<rect key="frame" x="0.0" y="612" width="335" height="63"/>
<rect key="frame" x="0.0" y="618" width="335" height="63"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Menu Fade Status Bar" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Gtc-KE-FIO">
<rect key="frame" x="0.0" y="17.5" width="168.5" height="20.5"/>
@@ -236,7 +234,7 @@
</constraints>
</scrollView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="← Swipe Screen Edges in View →" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ma4-O6-wOT">
<rect key="frame" x="87.5" y="643" width="200.5" height="16"/>
<rect key="frame" x="87" y="643" width="201.5" height="16"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -291,9 +289,10 @@
<!--Side Menu Navigation Controller-->
<scene sceneID="Zbc-0f-8nT">
<objects>
<navigationController storyboardIdentifier="LeftMenuNavigationController" navigationBarHidden="YES" id="DuX-EW-0mP" customClass="UISideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
<navigationController storyboardIdentifier="LeftMenuNavigationController" navigationBarHidden="YES" id="DuX-EW-0mP" customClass="SideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
<navigationItem key="navigationItem" id="ipz-Lx-Wgf"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="35F-wh-r6h">
<rect key="frame" x="0.0" y="-20" width="0.0" height="0.0"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<userDefinedRuntimeAttributes>
@@ -312,13 +311,13 @@
<objects>
<tableViewController id="V6g-oO-Tbm" customClass="SideMenuTableViewController" customModule="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="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<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="custom" customColorSpace="sRGB"/>
<inset key="separatorInset" minX="15" minY="0.0" maxX="8" maxY="0.0"/>
<view key="tableFooterView" contentMode="scaleToFill" id="vVB-ag-TnU">
<rect key="frame" x="0.0" y="132" width="375" height="0.0"/>
<rect key="frame" x="0.0" y="188" width="375" height="0.0"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
@@ -326,14 +325,14 @@
<tableViewSection id="gP8-eA-dcW">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="4WI-Ed-3Gr" style="IBUITableViewCellStyleDefault" id="7tx-O6-zAs" customClass="UITableViewVibrantCell" customModule="SideMenu">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="7tx-O6-zAs" id="K0u-J2-Ab7">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Push View Controller 1" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="4WI-Ed-3Gr">
<rect key="frame" x="15" y="0.0" width="344" height="43.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -347,14 +346,14 @@
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="DpJ-hV-lmw" style="IBUITableViewCellStyleDefault" id="f9Q-QP-TZ6" customClass="UITableViewVibrantCell" customModule="SideMenu">
<rect key="frame" x="0.0" y="44" width="375" height="44"/>
<rect key="frame" x="0.0" y="72" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="f9Q-QP-TZ6" id="i3p-Ya-AvO">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Push View Controller 2" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="DpJ-hV-lmw">
<rect key="frame" x="15" y="0.0" width="344" height="43.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -368,14 +367,14 @@
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="mAf-mx-C48" style="IBUITableViewCellStyleDefault" id="dc6-l8-0cu" customClass="UITableViewVibrantCell" customModule="SideMenu">
<rect key="frame" x="0.0" y="88" width="375" height="44"/>
<rect key="frame" x="0.0" y="116" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dc6-l8-0cu" id="gyo-JQ-fx5">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Push View Controller 3" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="mAf-mx-C48">
<rect key="frame" x="15" y="0.0" width="344" height="43.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -407,7 +406,7 @@
<objects>
<viewController id="BYZ-38-t0r" customClass="PresentedViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.80000001190000003" green="1" blue="0.40000000600000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="tWG-DO-ZIZ"/>
@@ -423,8 +422,9 @@
<!--Side Menu Navigation Controller-->
<scene sceneID="kei-0w-mFw">
<objects>
<navigationController storyboardIdentifier="RightMenuNavigationController" navigationBarHidden="YES" id="z7k-fk-pfc" customClass="UISideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
<navigationController storyboardIdentifier="RightMenuNavigationController" navigationBarHidden="YES" id="z7k-fk-pfc" customClass="SideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="qOd-yQ-2i8">
<rect key="frame" x="0.0" y="-20" width="0.0" height="0.0"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
@@ -440,12 +440,12 @@
<objects>
<tableViewController id="Ol4-YR-KUL" customClass="SideMenuTableViewController" customModule="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="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<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="375" height="0.0"/>
<rect key="frame" x="0.0" y="188" width="375" height="0.0"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
@@ -453,14 +453,14 @@
<tableViewSection id="xTE-WH-UeX">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="NLA-8t-ufi" style="IBUITableViewCellStyleDefault" id="8Ng-b4-4hH" customClass="UITableViewVibrantCell" customModule="SideMenu">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="8Ng-b4-4hH" id="U5K-l9-XWv">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Present View Controller 1" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="NLA-8t-ufi">
<rect key="frame" x="15" y="0.0" width="344" height="43.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -474,14 +474,14 @@
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="IdU-2D-zHb" style="IBUITableViewCellStyleDefault" id="Eok-gX-LwQ" customClass="UITableViewVibrantCell" customModule="SideMenu">
<rect key="frame" x="0.0" y="44" width="375" height="44"/>
<rect key="frame" x="0.0" y="72" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Eok-gX-LwQ" id="IOJ-bC-bNt">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Present View Controller 2" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="IdU-2D-zHb">
<rect key="frame" x="15" y="0.0" width="344" height="43.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -495,14 +495,14 @@
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="6x7-O7-DkG" style="IBUITableViewCellStyleDefault" id="41i-KK-YM3" customClass="UITableViewVibrantCell" customModule="SideMenu">
<rect key="frame" x="0.0" y="88" width="375" height="44"/>
<rect key="frame" x="0.0" y="116" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="41i-KK-YM3" id="629-G3-Agl">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Present View Controller 3" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6x7-O7-DkG">
<rect key="frame" x="15" y="0.0" width="344" height="43.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -534,11 +534,11 @@
<objects>
<viewController id="uMV-sw-TbB" customClass="PresentedViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="087-P6-J9s">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TJh-vs-sd4">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<state key="normal" title="Dismiss">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
@@ -573,11 +573,11 @@
<objects>
<viewController id="Upx-FH-Mbv" customClass="PresentedViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="efR-Hd-Gxy">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cKk-fD-whk">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<state key="normal" title="Dismiss">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
@@ -612,11 +612,11 @@
<objects>
<viewController id="EG7-2X-5hP" customClass="PresentedViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="vac-ts-bf9">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="a17-pq-WAQ">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<state key="normal" title="Dismiss">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
@@ -651,7 +651,7 @@
<objects>
<viewController id="u7M-mb-V6o" customClass="PresentedViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="9Dr-7n-COJ">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="0.80000001190000003" blue="0.40000000600000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="hUi-v8-7VE"/>
@@ -669,7 +669,7 @@
<objects>
<viewController id="b5t-IX-0yu" customClass="PresentedViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ias-bH-Sau">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="647"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="0.40000000600000002" blue="0.40000000600000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="bHF-BB-8F0"/>
+12 -11
View File
@@ -22,17 +22,18 @@ class MainViewController: UIViewController {
super.viewDidLoad()
setupSideMenu()
updateUI(settings: SideMenuSettings())
updateMenus()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let sideMenuNavigationController = segue.destination as? UISideMenuNavigationController else { return }
guard let sideMenuNavigationController = segue.destination as? SideMenuNavigationController else { return }
sideMenuNavigationController.settings = makeSettings()
}
private func setupSideMenu() {
// Define the menus
SideMenuManager.default.leftMenuNavigationController = storyboard?.instantiateViewController(withIdentifier: "LeftMenuNavigationController") as? UISideMenuNavigationController
SideMenuManager.default.rightMenuNavigationController = storyboard?.instantiateViewController(withIdentifier: "RightMenuNavigationController") as? UISideMenuNavigationController
SideMenuManager.default.leftMenuNavigationController = storyboard?.instantiateViewController(withIdentifier: "LeftMenuNavigationController") as? SideMenuNavigationController
SideMenuManager.default.rightMenuNavigationController = storyboard?.instantiateViewController(withIdentifier: "RightMenuNavigationController") as? SideMenuNavigationController
// 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!
@@ -43,7 +44,7 @@ class MainViewController: UIViewController {
private func updateUI(settings: SideMenuSettings) {
let styles:[UIBlurEffect.Style] = [.dark, .light, .extraLight]
if let menuBlurEffectStyle = settings.blurEffectStyle {
blurSegmentControl.selectedSegmentIndex = styles.firstIndex(of: menuBlurEffectStyle) ?? 0
blurSegmentControl.selectedSegmentIndex = (styles.firstIndex(of: menuBlurEffectStyle) ?? 0) + 1
} else {
blurSegmentControl.selectedSegmentIndex = 0
}
@@ -53,7 +54,7 @@ class MainViewController: UIViewController {
menuScaleFactorSlider.value = Float(settings.presentationStyle.menuScaleFactor)
presentingAlphaSlider.value = Float(settings.presentationStyle.presentingEndAlpha)
presentingScaleFactorSlider.value = Float(settings.presentationStyle.presentingScaleFactor)
screenWidthSlider.value = Float(settings.menuWidth / view.frame.width)
screenWidthSlider.value = Float(settings.menuWidth / min(view.frame.width, view.frame.height))
shadowOpacitySlider.value = Float(settings.presentationStyle.onTopShadowOpacity)
}
@@ -88,7 +89,7 @@ class MainViewController: UIViewController {
var settings = SideMenuSettings()
settings.presentationStyle = presentationStyle
settings.menuWidth = view.frame.width * CGFloat(screenWidthSlider.value)
settings.menuWidth = min(view.frame.width, view.frame.height) * CGFloat(screenWidthSlider.value)
let styles:[UIBlurEffect.Style?] = [nil, .dark, .light, .extraLight]
settings.blurEffectStyle = styles[blurSegmentControl.selectedSegmentIndex]
settings.statusBarEndAlpha = blackOutStatusBar.isOn ? 1 : 0
@@ -97,21 +98,21 @@ class MainViewController: UIViewController {
}
}
extension MainViewController: UISideMenuNavigationControllerDelegate {
extension MainViewController: SideMenuNavigationControllerDelegate {
func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Appearing! (animated: \(animated))")
}
func sideMenuDidAppear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuDidAppear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Appeared! (animated: \(animated))")
}
func sideMenuWillDisappear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuWillDisappear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Disappearing! (animated: \(animated))")
}
func sideMenuDidDisappear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuDidDisappear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Disappeared! (animated: \(animated))")
}
}
+2 -3
View File
@@ -6,7 +6,6 @@
// Copyright © 2016 CocoaPods. All rights reserved.
//
import Foundation
import SideMenu
class SideMenuTableViewController: UITableViewController {
@@ -17,7 +16,7 @@ class SideMenuTableViewController: UITableViewController {
// refresh cell blur effect in case it changed
tableView.reloadData()
guard let menu = navigationController as? UISideMenuNavigationController, menu.blurEffectStyle == nil else {
guard let menu = navigationController as? SideMenuNavigationController, menu.blurEffectStyle == nil else {
return
}
@@ -31,7 +30,7 @@ class SideMenuTableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt: indexPath) as! UITableViewVibrantCell
if let menu = navigationController as? UISideMenuNavigationController {
if let menu = navigationController as? SideMenuNavigationController {
cell.blurEffectStyle = menu.blurEffectStyle
}
+82
View File
@@ -0,0 +1,82 @@
//
// ExampleTests.swift
// ExampleTests
//
// Created by Jon Kent on 8/10/19.
// Copyright © 2019 jonkykong. All rights reserved.
//
import XCTest
class ExampleTests: XCTestCase {
private let styleTitles = ["Slide In", "Slide Out", "In + Out", "Dissolve"]
private let swipeHere = "Swipe Here"
private let app = XCUIApplication()
private var mainViewController: XCUIElement {
return app.navigationBars[swipeHere]
}
private var mainViewControllerNavigation: XCUIElement {
return mainViewController.otherElements[swipeHere]
}
override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
XCUIApplication().launch()
// In UI tests its important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testTapLeft() {
let elementsQuery = app.scrollViews.otherElements
for title in styleTitles {
elementsQuery.buttons[title].tap()
mainViewController.buttons["Left Menu"].tap()
app.tables/*@START_MENU_TOKEN@*/.staticTexts["Push View Controller 1"]/*[[".cells.staticTexts[\"Push View Controller 1\"]",".staticTexts[\"Push View Controller 1\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
app.navigationBars["You Can Still Swipe!"].buttons[swipeHere].tap()
validate()
}
}
func testTapRight() {
let elementsQuery = app.scrollViews.otherElements
for title in styleTitles {
elementsQuery.buttons[title].tap()
mainViewController.buttons["Right Menu"].tap()
app.tables/*@START_MENU_TOKEN@*/.staticTexts["Present View Controller 1"]/*[[".cells.staticTexts[\"Present View Controller 1\"]",".staticTexts[\"Present View Controller 1\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
app.buttons["Dismiss"].tap()
validate()
}
}
func testSwiping() {
mainViewControllerNavigation.swipeRight()
let element = app.children(matching: .window).element(boundBy: 0).children(matching: .other).element
element.swipeLeft()
validate()
element.swipeLeft()
mainViewControllerNavigation.swipeLeft()
element.swipeRight()
validate()
}
private func validate() {
XCTAssertTrue(mainViewController.exists)
}
/* TODO - More tests:
- Rotation
- All menu settings
*/
}
+1 -3
View File
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@@ -16,8 +16,6 @@
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
-29
View File
@@ -1,29 +0,0 @@
import UIKit
import XCTest
import SideMenu
class Tests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure() {
// Put the code you want to measure the time of here.
}
}
}
+17
View File
@@ -0,0 +1,17 @@
// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "SideMenu",
products: [
.library(name: "SideMenu", targets: ["SideMenu"])
],
dependencies: [],
targets: [
.target(name: "SideMenu", path: "Pod/Classes")
],
swiftLanguageVersions: [.v4_2, .v5]
)
@@ -5,184 +5,192 @@
// Created by Jon Kent on 7/3/19.
//
import UIKit
// Deprecations; to be removed at a future date.
extension SideMenuManager {
@available(*, deprecated, renamed: "leftMenuNavigationController")
open var menuLeftNavigationController: UISideMenuNavigationController? {
open var menuLeftNavigationController: SideMenuNavigationController? {
get { return nil }
set {}
}
@available(*, deprecated, renamed: "rightMenuNavigationController")
open var menuRightNavigationController: UISideMenuNavigationController? {
open var menuRightNavigationController: SideMenuNavigationController? {
get { return nil }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuPresentMode: SideMenuPresentationStyle {
get { return .viewSlideOut }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
public var menuPushStyle: MenuPushStyle {
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuPushStyle: SideMenuPushStyle {
get { return .default }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAllowPushOfSameClassTwice: Bool {
get { return true }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuWidth: CGFloat {
get { return 0 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationPresentDuration: Double {
get { return 0.35 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationDismissDuration: Double {
get { return 0.35 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationCompleteGestureDuration: Double {
get { return 0.35 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuAnimationFadeStrength: CGFloat {
get { return 0 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuAnimationTransformScaleFactor: CGFloat {
get { return 1 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuAnimationBackgroundColor: UIColor? {
get { return nil }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuShadowOpacity: Float {
get { return 0.5 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuShadowColor: UIColor {
get { return .black }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuShadowRadius: CGFloat {
get { return 5 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuPresentingViewControllerUserInteractionEnabled: Bool {
get { return false }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuPresentationStyle class.")
public var menuParallaxStrength: Int {
get { return 0 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuFadeStatusBar: Bool {
get { return true }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationOptions: UIView.AnimationOptions {
get { return .curveEaseInOut }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationCompletionCurve: UIView.AnimationCurve {
get { return .easeIn }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationUsingSpringWithDamping: CGFloat {
get { return 1 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAnimationInitialSpringVelocity: CGFloat {
get { return 1 }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuDismissOnPush: Bool {
get { return true }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuAlwaysAnimate: Bool {
get { return false }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuDismissWhenBackgrounded: Bool {
get { return true }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuBlurEffectStyle: UIBlurEffect.Style? {
get { return nil }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public weak var menuLeftSwipeToDismissGesture: UIPanGestureRecognizer? {
get { return nil }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public weak var menuRightSwipeToDismissGesture: UIPanGestureRecognizer? {
get { return nil }
set {}
}
@available(*, deprecated, message: "This property has been moved to the UISideMenuNavigationController class.")
@available(*, deprecated, message: "This property has been moved to the SideMenuNavigationController class.")
public var menuEnableSwipeGestures: Bool {
get { return true }
set {}
}
@available(*, deprecated, renamed: "SideMenuPresentStyle")
@available(*, deprecated, renamed: "enableSwipeToDismissGesture")
public var enableSwipeGestures: Bool {
get { return true }
set {}
}
@available(*, deprecated, renamed: "SideMenuPresentationStyle")
public typealias MenuPresentMode = SideMenuPresentationStyle
@available(*, deprecated, renamed: "addScreenEdgePanGesturesToPresent")
@@ -200,3 +208,9 @@ extension SideMenuPresentationStyle {
@available(*, deprecated, renamed: "viewSlideOutMenuIn")
public static var viewSlideInOut: SideMenuPresentationStyle { return viewSlideOutMenuIn }
}
@available(*, deprecated, renamed: "SideMenuNavigationController")
public typealias UISideMenuNavigationController = SideMenuNavigationController
@available(*, deprecated, renamed: "SideMenuNavigationControllerDelegate")
public typealias UISideMenuNavigationControllerDelegate = SideMenuNavigationControllerDelegate
+53 -8
View File
@@ -5,22 +5,22 @@
// Created by Jon Kent on 7/1/19.
//
import Foundation
import UIKit
extension NSObject: InitializableClass {}
internal extension UIView {
@discardableResult func untransformed(_ block: () -> CGFloat) -> CGFloat {
let transform = self.transform
self.transform = .identity
let t = transform
transform = .identity
let value = block()
self.transform = transform
transform = t
return value
}
func bringToFront() {
self.superview?.bringSubviewToFront(self)
superview?.bringSubviewToFront(self)
}
func untransform(_ block: () -> Void) {
@@ -29,29 +29,67 @@ internal extension UIView {
return 0
}
}
static func animationsEnabled(_ block: () -> Void) {
let a = areAnimationsEnabled
setAnimationsEnabled(true)
block()
setAnimationsEnabled(a)
}
}
internal extension UIViewController {
// View controller actively displayed in that layer. It may not be visible if it's presenting another view controller.
var activeViewController: UIViewController {
switch self {
case let navigationController as UINavigationController:
return navigationController.visibleViewController?.activeViewController ?? self
return navigationController.topViewController?.activeViewController ?? self
case let tabBarController as UITabBarController:
return tabBarController.selectedViewController?.activeViewController ?? self
case let splitViewController as UISplitViewController:
return splitViewController.viewControllers.last?.activeViewController ?? self
default:
return presentedViewController?.activeViewController ?? self
return self
}
}
// Indicates if the menu is anywhere in the view hierarchy, even if covered by another view controller.
// View controller being displayed on screen to the user.
var topMostViewController: UIViewController {
let activeViewController = self.activeViewController
return activeViewController.presentingViewController?.topMostViewController ?? activeViewController
}
var containerViewController: UIViewController {
return navigationController?.containerViewController ??
tabBarController?.containerViewController ??
splitViewController?.containerViewController ??
self
}
@objc var isHidden: Bool {
return presentingViewController == nil
}
}
internal extension UIGestureRecognizer {
convenience init(addTo view: UIView, target: Any, action: Selector) {
self.init()
addTarget(target, action: action)
view.addGestureRecognizer(self)
}
convenience init?(addTo view: UIView?, target: Any, action: Selector) {
guard let view = view else { return nil }
self.init(addTo: view, target: target, action: action)
}
func remove() {
view?.removeGestureRecognizer(self)
}
}
internal extension UIPanGestureRecognizer {
var canSwitch: Bool {
@@ -70,3 +108,10 @@ internal extension UIPanGestureRecognizer {
} ?? 0
}
}
internal extension UIApplication {
var keyWindow: UIWindow? {
return UIApplication.shared.windows.filter { $0.isKeyWindow }.first
}
}
+4 -3
View File
@@ -10,8 +10,8 @@ import Foundation
internal protocol InitializableClass: class {
init()
}
extension InitializableClass {
extension InitializableClass {
init(_ block: (Self) -> Void) {
self.init()
block(self)
@@ -23,10 +23,11 @@ extension InitializableClass {
}
}
internal protocol InitializableStruct {
public protocol InitializableStruct {
init()
}
internal extension InitializableStruct {
public extension InitializableStruct {
init(_ block: (inout Self) -> Void) {
self.init()
block(&self)
-73
View File
@@ -1,73 +0,0 @@
//
// Models.swift
// SideMenu
//
// Created by Jon Kent on 7/3/19.
//
import Foundation
internal protocol MenuModel: TransitionModel {
/// Prevents the same view controller (or a view controller of the same class) from being pushed more than once. Defaults to true.
var allowPushOfSameClassTwice: Bool { get }
/// Forces menus to always animate when appearing or disappearing, regardless of a pushed view controller's animation.
var alwaysAnimate: Bool { get }
/**
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.
*/
var blurEffectStyle: UIBlurEffect.Style? { get }
/// Animation curve of the remaining animation when the menu is partially dismissed with gestures. Default is .easeIn.
var completionCurve: UIView.AnimationCurve { get }
/// Automatically dismisses the menu when another view is presented from it.
var dismissOnPresent: Bool { get }
/// Automatically dismisses the menu when another view controller is pushed from it.
var dismissOnPush: Bool { get }
/// Automatically dismisses the menu when the screen is rotated.
var dismissOnRotation: Bool { get }
/// Automatically dismisses the menu when app goes to the background.
var dismissWhenBackgrounded: Bool { get }
/// Enable or disable gestures that would swipe to dismiss the menu. Default is true.
var enableSwipeGestures: Bool { get }
/**
The push style of the menu.
There are six modes in MenuPushStyle:
- defaultBehavior: The view controller is pushed onto the stack.
- popWhenPossible: If a view controller already in the stack is of the same class as the pushed view controller, the stack is instead popped back to the existing view controller. This behavior can help users from getting lost in a deep navigation stack.
- preserve: If a view controller already in the stack is of the same class as the pushed view controller, the existing view controller is pushed to the end of the stack. This behavior is similar to a UITabBarController.
- preserveAndHideBackButton: Same as .preserve and back buttons are automatically hidden.
- replace: Any existing view controllers are released from the stack and replaced with the pushed view controller. Back buttons are automatically hidden. This behavior is ideal if view controllers require a lot of memory or their state doesn't need to be preserved..
- subMenu: Unlike all other behaviors that push using the menu's presentingViewController, this behavior pushes view controllers within the menu. Use this behavior if you want to display a sub menu.
*/
var pushStyle: MenuPushStyle { get }
}
internal protocol TransitionModel: PresentationModel {
/// The animation options when a menu is displayed. Ignored when displayed with a gesture.
var animationOptions: UIView.AnimationOptions { get }
/// Duration of the remaining animation when the menu is partially dismissed with gestures. Default is 0.35 seconds.
var completeGestureDuration: Double { get }
/// Duration of the animation when the menu is dismissed without gestures. Default is 0.35 seconds.
var dismissDuration: Double { get }
/// The animation initial spring velocity when a menu is displayed. Ignored when displayed with a gesture.
var initialSpringVelocity: CGFloat { get }
/// Duration of the animation when the menu is presented without gestures. Default is 0.35 seconds.
var presentDuration: Double { get }
/// The animation spring damping when a menu is displayed. Ignored when displayed with a gesture.
var usingSpringWithDamping: CGFloat { get }
}
internal protocol PresentationModel {
/// Draws `presentStyle.backgroundColor` behind the status bar. Default is 1.
var statusBarEndAlpha: CGFloat { get }
/// Enable or disable interaction with the presenting view controller while the menu is displayed. Enabling may make it difficult to dismiss the menu or cause exceptions if the user tries to present and already presented menu. `presentingViewControllerUseSnapshot` must also set to false. Default is false.
var presentingViewControllerUserInteractionEnabled: Bool { get }
/// Use a snapshot for the presenting vierw controller while the menu is displayed. Useful when layout changes occur during transitions. Not recommended for apps that support rotation. Default is false.
var presentingViewControllerUseSnapshot: Bool { get }
/// The presentation style of the menu.
var presentationStyle: SideMenuPresentationStyle { get }
/// Width of the menu when presented on screen, showing the existing view controller in the remaining space. Default is zero.
var menuWidth: CGFloat { get }
}
+15 -7
View File
@@ -9,26 +9,34 @@ import Foundation
internal enum Print: String { case
cannotPush = "Attempt to push a View Controller from %@ where its navigationController == nil. It must be embedded in a UINavigationController for this to work.",
emptyMenu = "The menu doesn't have a view controller to show! UISideMenuNavigationController needs a view controller to display just like a UINavigationController.",
menuAlreadyAssigned = "%@ was already assigned to the %@ of %@. When using multiple SideMenuManagers you may want to use new instances of UISideMenuNavigationController instead of existing instances to avoid crashes if the menu is presented more than once.",
emptyMenu = "The menu doesn't have a view controller to show! SideMenuNavigationController needs a view controller to display just like a UINavigationController.",
menuAlreadyAssigned = "%@ was already assigned to the %@ of %@. When using multiple SideMenuManagers you may want to use new instances of SideMenuNavigationController instead of existing instances to avoid crashes if the menu is presented more than once.",
menuInUse = "%@ cannot be modified while it's presented.",
panGestureAdded = "%@ was called before %@ or %@ was set. Gestures will not work without a menu.",
property = "a menu's %@ property can only be changed when it is hidden.",
property = "A menu's %@ property can only be changed when it is hidden.",
screenGestureAdded = "%@ was called before %@ was set. The gesture will not work without a menu. Use %@ to add gestures for only one menu.",
transitioningDelegate = "SideMenu requires use of the transitioningDelegate. It cannot be modified."
internal static func warning(_ print: Print, arguments: CVarArg..., required: Bool = false) {
warning(String(format: print.rawValue, arguments), required: required)
enum PropertyName: String { case
leftSide
}
internal static func warning(_ print: Print, required: Bool = false) {
static func warning(_ print: Print, arguments: CVarArg..., required: Bool = false) {
warning(String(format: print.rawValue, arguments: arguments), required: required)
}
static func warning(_ print: Print, arguments: PropertyName..., required: Bool = false) {
warning(String(format: print.rawValue, arguments: arguments.map { $0.rawValue }), required: required)
}
static func warning(_ print: Print, required: Bool = false) {
warning(print.rawValue, required: required)
}
}
private extension Print {
private static func warning(_ message: String, required: Bool = false) {
static func warning(_ message: String, required: Bool = false) {
let message = "SideMenu Warning: \(message)"
if required {
+6 -20
View File
@@ -9,32 +9,18 @@ import Foundation
internal final class Protected<T: Equatable> {
typealias ConditionBlock = (T) -> Bool
typealias Block = (T) -> Void
typealias ConditionBlock = (_ oldValue: T, T) -> T
private var _value: T
private var conditionBlock: ConditionBlock
private var thenBlock: Block?
private var elseBlock: Block?
private var condition: ConditionBlock
public var value: T {
get {
return _value
}
set {
guard conditionBlock(_value) else {
elseBlock?(_value)
return
}
_value = newValue
thenBlock?(_value)
}
get { return _value }
set { _value = condition(_value, newValue) }
}
init(_ value: T, if conditionBlock: @escaping ConditionBlock, then thenBlock: Block? = nil, else elseBlock: Block? = nil) {
init(_ value: T, when condition: @escaping ConditionBlock) {
self._value = value
self.conditionBlock = conditionBlock
self.thenBlock = thenBlock
self.elseBlock = elseBlock
self.condition = condition
}
}
@@ -0,0 +1,204 @@
//
// SideMenuAnimationController.swift
// SideMenu
//
// Created by Jon Kent on 10/24/18.
//
import UIKit
internal protocol AnimationModel {
/// The animation options when a menu is displayed. Ignored when displayed with a gesture.
var animationOptions: UIView.AnimationOptions { get }
/// Duration of the remaining animation when the menu is partially dismissed with gestures. Default is 0.35 seconds.
var completeGestureDuration: Double { get }
/// Duration of the animation when the menu is dismissed without gestures. Default is 0.35 seconds.
var dismissDuration: Double { get }
/// The animation initial spring velocity when a menu is displayed. Ignored when displayed with a gesture.
var initialSpringVelocity: CGFloat { get }
/// Duration of the animation when the menu is presented without gestures. Default is 0.35 seconds.
var presentDuration: Double { get }
/// The animation spring damping when a menu is displayed. Ignored when displayed with a gesture.
var usingSpringWithDamping: CGFloat { get }
}
internal protocol SideMenuAnimationControllerDelegate: class {
func sideMenuAnimationController(_ animationController: SideMenuAnimationController, didDismiss viewController: UIViewController)
func sideMenuAnimationController(_ animationController: SideMenuAnimationController, didPresent viewController: UIViewController)
}
internal final class SideMenuAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
typealias Model = AnimationModel & PresentationModel
private var config: Model
private weak var containerView: UIView?
private let leftSide: Bool
private var presentationController: SideMenuPresentationController!
private unowned var presentedViewController: UIViewController?
private unowned var presentingViewController: UIViewController?
weak var delegate: SideMenuAnimationControllerDelegate?
init(config: Model, leftSide: Bool, delegate: SideMenuAnimationControllerDelegate? = nil) {
self.config = config
self.leftSide = leftSide
self.delegate = delegate
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard
let presentedViewController = transitionContext.presentedViewController,
let presentingViewController = transitionContext.presentingViewController
else { return }
if transitionContext.isPresenting {
self.containerView = transitionContext.containerView
self.presentedViewController = presentedViewController
self.presentingViewController = presentingViewController
self.presentationController = SideMenuPresentationController(
config: config,
leftSide: leftSide,
presentedViewController: presentedViewController,
presentingViewController: presentingViewController,
containerView: transitionContext.containerView
)
}
transition(using: transitionContext)
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
guard let transitionContext = transitionContext else { return 0 }
return duration(presenting: transitionContext.isPresenting, interactive: transitionContext.isInteractive)
}
func animationEnded(_ transitionCompleted: Bool) {
guard let presentedViewController = presentedViewController else { return }
if presentedViewController.isHidden {
delegate?.sideMenuAnimationController(self, didDismiss: presentedViewController)
} else {
delegate?.sideMenuAnimationController(self, didPresent: presentedViewController)
}
}
func transition(presenting: Bool, animated: Bool = true, interactive: Bool = false, alongsideTransition: (() -> Void)? = nil, complete: Bool = true, completion: ((Bool) -> Void)? = nil) {
transitionWillBegin(presenting: presenting)
transition(presenting: presenting,
animated: animated,
interactive: interactive,
animations: { [weak self] in
guard let self = self else { return }
self.transition(presenting: presenting)
alongsideTransition?()
}, completion: { [weak self] _ in
guard let self = self else { return }
if complete {
self.transitionDidEnd(presenting: presenting, completed: true)
}
completion?(true)
})
}
func layout() {
presentationController.containerViewWillLayoutSubviews()
}
}
private extension SideMenuAnimationController {
func duration(presenting: Bool, interactive: Bool) -> Double {
if interactive { return config.completeGestureDuration }
return presenting ? config.presentDuration : config.dismissDuration
}
func transitionWillBegin(presenting: Bool) {
// prevent any other menu gestures from firing
containerView?.isUserInteractionEnabled = false
if presenting {
presentationController.presentationTransitionWillBegin()
} else {
presentationController.dismissalTransitionWillBegin()
}
}
func transition(presenting: Bool) {
if presenting {
presentationController.presentationTransition()
} else {
presentationController.dismissalTransition()
}
}
func transitionDidEnd(presenting: Bool, completed: Bool) {
if presenting {
presentationController.presentationTransitionDidEnd(completed)
} else {
presentationController.dismissalTransitionDidEnd(completed)
}
containerView?.isUserInteractionEnabled = true
}
func transition(using transitionContext: UIViewControllerContextTransitioning) {
transitionWillBegin(presenting: transitionContext.isPresenting)
transition(presenting: transitionContext.isPresenting,
animated: transitionContext.isAnimated,
interactive: transitionContext.isInteractive,
animations: { [weak self] in
guard let self = self else { return }
self.transition(presenting: transitionContext.isPresenting)
}, completion: { [weak self] _ in
guard let self = self else { return }
let completed = !transitionContext.transitionWasCancelled
self.transitionDidEnd(presenting: transitionContext.isPresenting, completed: completed)
transitionContext.completeTransition(completed)
})
}
func transition(presenting: Bool, animated: Bool = true, interactive: Bool = false, animations: @escaping (() -> Void) = {}, completion: @escaping ((Bool) -> Void) = { _ in }) {
if !animated {
animations()
completion(true)
return
}
let duration = self.duration(presenting: presenting, interactive: interactive)
if interactive {
// IMPORTANT: The non-interactive animation block will not complete if adapted for interactive. The below animation block must be used!
UIView.animate(
withDuration: duration,
delay: duration, // HACK: If zero, the animation briefly flashes in iOS 11.
options: .curveLinear,
animations: animations,
completion: completion
)
return
}
UIView.animate(
withDuration: duration,
delay: 0,
usingSpringWithDamping: config.usingSpringWithDamping,
initialSpringVelocity: config.initialSpringVelocity,
options: config.animationOptions,
animations: animations,
completion: completion
)
}
}
private extension UIViewControllerContextTransitioning {
var isPresenting: Bool {
return viewController(forKey: .from)?.presentedViewController === viewController(forKey: .to)
}
var presentingViewController: UIViewController? {
return viewController(forKey: isPresenting ? .from : .to)
}
var presentedViewController: UIViewController? {
return viewController(forKey: isPresenting ? .to : .from)
}
}
+11 -18
View File
@@ -7,10 +7,6 @@
import UIKit
internal protocol SideMenuInteractable {
func handle(state: SideMenuInteractionController.State)
}
internal final class SideMenuInteractionController: UIPercentDrivenInteractiveTransition {
enum State { case
@@ -44,20 +40,6 @@ internal final class SideMenuInteractionController: UIPercentDrivenInteractiveTr
guard !isCancelled && !isFinished else { return }
super.update(percentComplete)
}
}
private extension SideMenuInteractionController {
@objc func handleNotification(notification: NSNotification) {
switch notification.name {
case UIApplication.didEnterBackgroundNotification:
cancel()
default: break
}
}
}
extension SideMenuInteractionController: SideMenuInteractable {
func handle(state: State) {
switch state {
@@ -70,3 +52,14 @@ extension SideMenuInteractionController: SideMenuInteractable {
}
}
}
private extension SideMenuInteractionController {
@objc func handleNotification(notification: NSNotification) {
switch notification.name {
case UIApplication.didEnterBackgroundNotification:
cancel()
default: break
}
}
}
+34 -28
View File
@@ -30,21 +30,14 @@ public class SideMenuManager: NSObject {
var name: String {
switch self {
case .left: return "menuLeftNavigationController"
case .right: return "menuRightNavigationController"
case .left: return "leftMenuNavigationController"
case .right: return "rightMenuNavigationController"
}
}
}
private var _leftMenu: Protected<Menu?> =
Protected(nil,
if: { $0?.isHidden != false },
else: { _ in Print.warning(.menuInUse, arguments: PresentDirection.left.name, required: true) } )
private var _rightMenu: Protected<Menu?> =
Protected(nil,
if: { $0?.isHidden != false },
else: { _ in Print.warning(.menuInUse, arguments: PresentDirection.right.name, required: true) } )
private var _leftMenu: Protected<Menu?> = Protected(nil) { SideMenuManager.setMenu(fromMenu: $0, toMenu: $1) }
private var _rightMenu: Protected<Menu?> = Protected(nil) { SideMenuManager.setMenu(fromMenu: $0, toMenu: $1) }
private var switching: Bool = false
@@ -57,14 +50,24 @@ public class SideMenuManager: NSObject {
}
/// The left menu.
open var leftMenuNavigationController: UISideMenuNavigationController? {
get { return _leftMenu.value }
open var leftMenuNavigationController: SideMenuNavigationController? {
get {
if _leftMenu.value?.isHidden == true {
_leftMenu.value?.leftSide = true
}
return _leftMenu.value
}
set(menu) { _leftMenu.value = menu }
}
/// The right menu.
open var rightMenuNavigationController: UISideMenuNavigationController? {
get { return _rightMenu.value }
open var rightMenuNavigationController: SideMenuNavigationController? {
get {
if _rightMenu.value?.isHidden == true {
_rightMenu.value?.leftSide = false
}
return _rightMenu.value
}
set(menu) { _rightMenu.value = menu }
}
@@ -123,6 +126,14 @@ internal extension SideMenuManager {
case false: rightMenuNavigationController = menu
}
}
private class func setMenu(fromMenu: Menu?, toMenu: Menu?) -> Menu? {
if fromMenu?.isHidden == false {
Print.warning(.menuInUse, arguments: PresentDirection.left.name, required: true)
return fromMenu
}
return toMenu
}
}
private extension SideMenuManager {
@@ -165,7 +176,7 @@ private extension SideMenuManager {
}
guard let menu = menu(forLeftSide: leftSide) else { return }
menu.presentFrom(activeViewController, interactively: true)
menu.present(topMostViewController, interactively: true)
}
activeMenu?.handleMenuPan(gesture, true)
@@ -191,12 +202,10 @@ private extension SideMenuManager {
func addScreenEdgeGesture(to view: UIView, edge: UIRectEdge) -> UIScreenEdgePanGestureRecognizer {
if let screenEdgeGestureRecognizer = view.gestureRecognizers?.first(where: { $0 is SideMenuScreenEdgeGestureRecognizer }) as? SideMenuScreenEdgeGestureRecognizer,
screenEdgeGestureRecognizer.edges == edge {
view.removeGestureRecognizer(screenEdgeGestureRecognizer)
screenEdgeGestureRecognizer.remove()
}
return SideMenuScreenEdgeGestureRecognizer {
return SideMenuScreenEdgeGestureRecognizer(addTo: view, target: self, action: #selector(handlePresentMenuScreenEdge(_:))).with {
$0.edges = edge
$0.addTarget(self, action: #selector(handlePresentMenuScreenEdge(_:)))
view.addGestureRecognizer($0)
}
}
@@ -204,22 +213,19 @@ private extension SideMenuManager {
if let panGestureRecognizer = view.gestureRecognizers?.first(where: { $0 is SideMenuPanGestureRecognizer }) as? SideMenuPanGestureRecognizer {
return panGestureRecognizer
}
return SideMenuPanGestureRecognizer {
$0.addTarget(self, action: #selector(handlePresentMenuPan(_:)))
view.addGestureRecognizer($0)
}
return SideMenuPanGestureRecognizer(addTo: view, target: self, action: #selector(handlePresentMenuPan(_:)))
}
private var activeViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController?.activeViewController
var topMostViewController: UIViewController? {
return UIApplication.shared.keyWindow?.rootViewController?.topMostViewController
}
}
extension SideMenuManager: UISideMenuNavigationControllerTransitionDelegate {
extension SideMenuManager: SideMenuNavigationControllerTransitionDelegate {
internal func sideMenuTransitionDidDismiss(menu: Menu) {
defer { switching = false }
guard switching, let switchToMenu = self.menu(forLeftSide: !menu.leftSide) else { return }
switchToMenu.presentFrom(activeViewController, interactively: true)
switchToMenu.present(topMostViewController, interactively: true)
}
}
@@ -1,5 +1,5 @@
//
// UISideMenuNavigationController.swift
// SideMenuNavigationController.swift
//
// Created by Jon Kent on 1/14/16.
// Copyright © 2016 Jon Kent. All rights reserved.
@@ -7,27 +7,73 @@
import UIKit
@objc public enum MenuPushStyle: Int { case
@objc public enum SideMenuPushStyle: Int { case
`default`,
popWhenPossible,
preserve,
preserveAndHideBackButton,
replace,
subMenu
internal var hidesBackButton: Bool {
switch self {
case .preserveAndHideBackButton, .replace: return true
case .default, .popWhenPossible, .preserve, .subMenu: return false
}
}
}
@objc public protocol UISideMenuNavigationControllerDelegate {
@objc optional func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool)
@objc optional func sideMenuDidAppear(menu: UISideMenuNavigationController, animated: Bool)
@objc optional func sideMenuWillDisappear(menu: UISideMenuNavigationController, animated: Bool)
@objc optional func sideMenuDidDisappear(menu: UISideMenuNavigationController, animated: Bool)
internal protocol MenuModel {
/// Prevents the same view controller (or a view controller of the same class) from being pushed more than once. Defaults to true.
var allowPushOfSameClassTwice: Bool { get }
/// Forces menus to always animate when appearing or disappearing, regardless of a pushed view controller's animation.
var alwaysAnimate: Bool { get }
/**
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.
*/
var blurEffectStyle: UIBlurEffect.Style? { get }
/// Animation curve of the remaining animation when the menu is partially dismissed with gestures. Default is .easeIn.
var completionCurve: UIView.AnimationCurve { get }
/// Automatically dismisses the menu when another view is presented from it.
var dismissOnPresent: Bool { get }
/// Automatically dismisses the menu when another view controller is pushed from it.
var dismissOnPush: Bool { get }
/// Automatically dismisses the menu when the screen is rotated.
var dismissOnRotation: Bool { get }
/// Automatically dismisses the menu when app goes to the background.
var dismissWhenBackgrounded: Bool { get }
/// Enable or disable a swipe gesture that dismisses the menu. Will not be triggered when `presentingViewControllerUserInteractionEnabled` is set to true. Default is true.
var enableSwipeToDismissGesture: Bool { get }
/// Enable or disable a tap gesture that dismisses the menu. Will not be triggered when `presentingViewControllerUserInteractionEnabled` is set to true. Default is true.
var enableTapToDismissGesture: Bool { get }
/**
The push style of the menu.
There are six modes in MenuPushStyle:
- defaultBehavior: The view controller is pushed onto the stack.
- popWhenPossible: If a view controller already in the stack is of the same class as the pushed view controller, the stack is instead popped back to the existing view controller. This behavior can help users from getting lost in a deep navigation stack.
- preserve: If a view controller already in the stack is of the same class as the pushed view controller, the existing view controller is pushed to the end of the stack. This behavior is similar to a UITabBarController.
- preserveAndHideBackButton: Same as .preserve and back buttons are automatically hidden.
- replace: Any existing view controllers are released from the stack and replaced with the pushed view controller. Back buttons are automatically hidden. This behavior is ideal if view controllers require a lot of memory or their state doesn't need to be preserved..
- subMenu: Unlike all other behaviors that push using the menu's presentingViewController, this behavior pushes view controllers within the menu. Use this behavior if you want to display a sub menu.
*/
var pushStyle: SideMenuPushStyle { get }
}
internal protocol UISideMenuNavigationControllerTransitionDelegate: class {
@objc public protocol SideMenuNavigationControllerDelegate {
@objc optional func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool)
@objc optional func sideMenuDidAppear(menu: SideMenuNavigationController, animated: Bool)
@objc optional func sideMenuWillDisappear(menu: SideMenuNavigationController, animated: Bool)
@objc optional func sideMenuDidDisappear(menu: SideMenuNavigationController, animated: Bool)
}
internal protocol SideMenuNavigationControllerTransitionDelegate: class {
func sideMenuTransitionDidDismiss(menu: Menu)
}
public struct SideMenuSettings: MenuModel {
public struct SideMenuSettings: SideMenuNavigationController.Model, InitializableStruct {
public var allowPushOfSameClassTwice: Bool = true
public var alwaysAnimate: Bool = true
public var animationOptions: UIView.AnimationOptions = .curveEaseInOut
@@ -39,7 +85,8 @@ public struct SideMenuSettings: MenuModel {
public var dismissOnPush: Bool = true
public var dismissOnRotation: Bool = true
public var dismissWhenBackgrounded: Bool = true
public var enableSwipeGestures: Bool = true
public var enableSwipeToDismissGesture: Bool = true
public var enableTapToDismissGesture: Bool = true
public var initialSpringVelocity: CGFloat = 1
public var menuWidth: CGFloat = {
let appScreenRect = UIApplication.shared.keyWindow?.bounds ?? UIWindow().bounds
@@ -50,44 +97,41 @@ public struct SideMenuSettings: MenuModel {
public var presentingViewControllerUseSnapshot: Bool = false
public var presentDuration: Double = 0.35
public var presentationStyle: SideMenuPresentationStyle = .viewSlideOut
public var pushStyle: MenuPushStyle = .default
public var pushStyle: SideMenuPushStyle = .default
public var statusBarEndAlpha: CGFloat = 1
public var usingSpringWithDamping: CGFloat = 1
public init() {}
public init(_ block: (inout SideMenuSettings) -> Void) {
self.init()
block(&self)
}
}
internal typealias Menu = UISideMenuNavigationController
internal typealias Menu = SideMenuNavigationController
@objcMembers
open class UISideMenuNavigationController: UINavigationController {
open class SideMenuNavigationController: UINavigationController {
private enum PropertyName: String { case
leftSide
internal typealias Model = MenuModel & PresentationModel & AnimationModel
private lazy var _leftSide = Protected(false) { [weak self] oldValue, newValue in
guard self?.isHidden != false else {
Print.warning(.property, arguments: .leftSide, required: true)
return oldValue
}
return newValue
}
private lazy var _leftSide = Protected(false,
if: { [weak self] _ in self?.isHidden != false },
else: { _ in Menu.elseCondition(.leftSide) } )
private weak var _sideMenuManager: SideMenuManager?
private weak var foundDelegate: UISideMenuNavigationControllerDelegate?
private weak var interactionController: SideMenuInteractionController?
private var interactive: Bool = false
private weak var foundViewController: UIViewController?
private var originalBackgroundColor: UIColor?
private var rotating: Bool = false
private var transitionController: SideMenuTransitionController?
/// Delegate for receiving appear and disappear related events. If `nil` the visible view controller that displays a `UISideMenuNavigationController` automatically receives these events.
internal weak var sideMenuDelegate: UISideMenuNavigationControllerDelegate?
/// Delegate for receiving appear and disappear related events. If `nil` the visible view controller that displays a `SideMenuNavigationController` automatically receives these events.
public weak var sideMenuDelegate: SideMenuNavigationControllerDelegate?
/// The swipe to dismiss gesture.
private(set) weak var swipeToDismissGesture: UIPanGestureRecognizer? = nil
open private(set) weak var swipeToDismissGesture: UIPanGestureRecognizer? = nil
/// The tap to dismiss gesture.
open private(set) weak var tapToDismissGesture: UITapGestureRecognizer? = nil
open var sideMenuManager: SideMenuManager {
get { return _sideMenuManager ?? SideMenuManager.default }
@@ -106,31 +150,25 @@ open class UISideMenuNavigationController: UINavigationController {
open var settings = SideMenuSettings() {
didSet {
setupBlur()
setupSwipeGestures()
if !enableSwipeToDismissGesture {
swipeToDismissGesture?.remove()
}
if !enableTapToDismissGesture {
tapToDismissGesture?.remove()
}
}
}
#if !STFU_SIDEMENU
// This override prevents newbie developers from creating black/blank menus and opening newbie issues.
// If you would like to remove this override, define STFU_SIDEMENU in the Active Compilation Conditions of your .plist file.
// Sorry for the inconvenience experienced developers :(
@available(*, unavailable, renamed: "init(rootViewController:)")
init() {
fatalError("init is not available")
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
setup()
}
#else
public init(_ block: (UISideMenuNavigationController) -> Void) {
self.init()
block(self)
}
#endif
public init(rootViewController: UIViewController, settings: SideMenuSettings) {
super.init(rootViewController: rootViewController)
public init(rootViewController: UIViewController, settings: SideMenuSettings = SideMenuSettings()) {
self.settings = settings
super.init(rootViewController: rootViewController)
setup()
}
required public init?(coder aDecoder: NSCoder) {
@@ -153,7 +191,7 @@ open class UISideMenuNavigationController: UINavigationController {
// Dismiss keyboard to prevent weird keyboard animations from occurring during transition
presentingViewController?.view.endEditing(true)
foundDelegate = nil
foundViewController = nil
activeDelegate?.sideMenuWillAppear?(menu: self, animated: animated)
}
@@ -174,24 +212,28 @@ open class UISideMenuNavigationController: UINavigationController {
override open func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
defer {
activeDelegate?.sideMenuWillDisappear?(menu: self, animated: animated)
}
guard !isBeingDismissed else { return }
// When presenting a view controller from the menu, the menu view gets moved into another transition view above our transition container
// which can break the visual layout we had before. So, we move the menu view back to its original transition view to preserve it.
if dismissOnPresent && !isBeingDismissed {
// We're presenting a view controller from the menu, so we need to hide the menu so it isn't showing when the presented view is dismissed.
if let presentingView = presentingViewController?.view, let containerView = presentingView.superview {
containerView.addSubview(view)
}
if let presentingView = presentingViewController?.view, let containerView = presentingView.superview {
containerView.addSubview(view)
}
if dismissOnPresent {
// We're presenting a view controller from the menu, so we need to hide the menu so it isn't showing when the presented view is dismissed.
transitionController?.transition(presenting: false, animated: animated, alongsideTransition: { [weak self] in
guard let self = self else { return }
self.activeDelegate?.sideMenuWillDisappear?(menu: self, animated: animated)
}, complete: false, completion: { [weak self] _ in
guard let self = self else { return }
self.activeDelegate?.sideMenuDidDisappear?(menu: self, animated: animated)
self.view.isHidden = true
}, complete: false, completion: { [weak self] _ in
guard let self = self else { return }
self.activeDelegate?.sideMenuDidDisappear?(menu: self, animated: animated)
self.view.isHidden = true
})
} else {
activeDelegate?.sideMenuWillDisappear?(menu: self, animated: animated)
}
}
@@ -202,7 +244,7 @@ open class UISideMenuNavigationController: UINavigationController {
// the view hierarchy leaving the screen black/empty. This is because the transition moves views within a container
// view, but dismissing without animation removes the container view before the original hierarchy is restored.
// This check corrects that.
if presentedViewController == nil && view.window == nil {
if let foundViewController = findViewController, foundViewController.view.window == nil {
transitionController?.transition(presenting: false, animated: false)
}
@@ -216,10 +258,10 @@ open class UISideMenuNavigationController: UINavigationController {
activeDelegate?.sideMenuDidDisappear?(menu: self, animated: animated)
if dismissOnPresent && !isBeingDismissed {
view.isHidden = true
} else {
if isBeingDismissed {
transitionController = nil
} else if dismissOnPresent {
view.isHidden = true
}
}
@@ -246,25 +288,55 @@ open class UISideMenuNavigationController: UINavigationController {
self.rotating = false
}
}
open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
transitionController?.layout()
}
override open func pushViewController(_ viewController: UIViewController, animated: Bool) {
let push = shouldPushViewController(viewController: viewController, animated: animated) { [weak self] _ in
self?.foundDelegate = nil
guard viewControllers.count > 0 else {
// NOTE: pushViewController is called by init(rootViewController: UIViewController)
// so we must perform the normal super method in this case
return super.pushViewController(viewController, animated: animated)
}
if push {
var alongsideTransition: (() -> Void)? = nil
if dismissOnPush {
alongsideTransition = { [weak self] in
guard let self = self else { return }
self.dismissAnimation(animated: animated || self.alwaysAnimate)
}
}
let pushed = SideMenuPushCoordinator(config:
.init(
allowPushOfSameClassTwice: allowPushOfSameClassTwice,
alongsideTransition: alongsideTransition,
animated: animated,
fromViewController: self,
pushStyle: pushStyle,
toViewController: viewController
)
).start()
if !pushed {
super.pushViewController(viewController, animated: animated)
}
}
override open var transitioningDelegate: UIViewControllerTransitioningDelegate? {
get { return self }
get {
transitionController = transitionController ?? SideMenuTransitionController(leftSide: leftSide, config: settings)
transitionController?.delegate = self
return transitionController
}
set { Print.warning(.transitioningDelegate, required: true) }
}
}
// Interface
extension UISideMenuNavigationController: MenuModel {
extension SideMenuNavigationController: SideMenuNavigationController.Model {
@IBInspectable open var allowPushOfSameClassTwice: Bool {
get { return settings.allowPushOfSameClassTwice }
@@ -321,9 +393,14 @@ extension UISideMenuNavigationController: MenuModel {
set { settings.dismissWhenBackgrounded = newValue }
}
@IBInspectable open var enableSwipeGestures: Bool {
get { return settings.enableSwipeGestures }
set { settings.enableSwipeGestures = newValue }
@IBInspectable open var enableSwipeToDismissGesture: Bool {
get { return settings.enableSwipeToDismissGesture }
set { settings.enableSwipeToDismissGesture = newValue }
}
@IBInspectable open var enableTapToDismissGesture: Bool {
get { return settings.enableTapToDismissGesture }
set { settings.enableTapToDismissGesture = newValue }
}
@IBInspectable open var initialSpringVelocity: CGFloat {
@@ -336,6 +413,11 @@ extension UISideMenuNavigationController: MenuModel {
get { return _leftSide.value }
set { _leftSide.value = newValue }
}
/// Indicates if the menu is anywhere in the view hierarchy, even if covered by another view controller.
open override var isHidden: Bool {
return super.isHidden
}
@IBInspectable open var menuWidth: CGFloat {
get { return settings.menuWidth }
@@ -362,7 +444,7 @@ extension UISideMenuNavigationController: MenuModel {
set { settings.presentationStyle = newValue }
}
@IBInspectable open var pushStyle: MenuPushStyle {
@IBInspectable open var pushStyle: SideMenuPushStyle {
get { return settings.pushStyle }
set { settings.pushStyle = newValue }
}
@@ -378,59 +460,20 @@ extension UISideMenuNavigationController: MenuModel {
}
}
// IMPORTANT: These methods must be declared open or they will not be called.
extension UISideMenuNavigationController: UIViewControllerTransitioningDelegate {
extension SideMenuNavigationController: SideMenuTransitionControllerDelegate {
open func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transitionController = SideMenuTransitionController(
config: self,
leftSide: leftSide,
delegate: self)
return transitionController
}
open func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return transitionController
}
open func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController(using: animator)
}
open func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController(using: animator)
}
open func interactionController(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
guard interactive else { return nil }
let interactionController = SideMenuInteractionController(cancelWhenBackgrounded: dismissWhenBackgrounded, completionCurve: completionCurve)
self.interactionController = interactionController
return interactionController
}
}
extension UISideMenuNavigationController: SideMenuTransitionControllerDelegate {
internal func sideMenuTransitionController(_ transitionController: SideMenuTransitionController, didDismiss viewController: UIViewController) {
func sideMenuTransitionController(_ transitionController: SideMenuTransitionController, didDismiss viewController: UIViewController) {
sideMenuManager.sideMenuTransitionDidDismiss(menu: self)
}
internal func sideMenuTransitionController(_ transitionController: SideMenuTransitionController, didPresent viewController: UIViewController) {
guard !presentingViewControllerUserInteractionEnabled else { return }
let panGesture = UIPanGestureRecognizer()
panGesture.cancelsTouchesInView = false
panGesture.addTarget(self, action: #selector(handleDismissMenuPan(_:)))
view.superview?.addGestureRecognizer(panGesture)
let tapGestureRecognizer = UITapGestureRecognizer()
tapGestureRecognizer.addTarget(self, action: #selector(handleDismissMenuTap(_:)))
tapGestureRecognizer.cancelsTouchesInView = false
view.superview?.addGestureRecognizer(tapGestureRecognizer)
func sideMenuTransitionController(_ transitionController: SideMenuTransitionController, didPresent viewController: UIViewController) {
swipeToDismissGesture?.remove()
swipeToDismissGesture = addSwipeToDismissGesture(to: view.superview)
tapToDismissGesture = addTapToDismissGesture(to: view.superview)
}
}
internal extension UISideMenuNavigationController {
internal extension SideMenuNavigationController {
func handleMenuPan(_ gesture: UIPanGestureRecognizer, _ presenting: Bool) {
let width = menuWidth
@@ -441,151 +484,68 @@ internal extension UISideMenuNavigationController {
if !presenting {
dismissMenu(interactively: true)
}
interactionController?.handle(state: .update(progress: progress))
transitionController?.handle(state: .update(progress: progress))
case .changed:
interactionController?.handle(state: .update(progress: progress))
transitionController?.handle(state: .update(progress: progress))
case .ended:
let velocity = gesture.xVelocity * factor(presenting)
let finished = velocity >= 100 || velocity >= -50 && abs(progress) >= 0.5
interactionController?.handle(state: finished ? .finish : .cancel)
transitionController?.handle(state: finished ? .finish : .cancel)
default:
interactionController?.handle(state: .cancel)
transitionController?.handle(state: .cancel)
}
}
func cancelMenuPan(_ gesture: UIPanGestureRecognizer) {
interactionController?.handle(state: .cancel)
transitionController?.handle(state: .cancel)
}
func dismissMenu(animated flag: Bool = true, interactively interactive: Bool = false, completion: (() -> Void)? = nil) {
guard !isHidden else { return }
self.interactive = interactive
transitionController?.interactive = interactive
dismiss(animated: flag, completion: completion)
}
// Note: although this method is syntactically reversed it allows the interactive property to scoped privately
func presentFrom(_ viewControllerToPresentFrom: UIViewController?, interactively interactive: Bool, completion: (() -> Void)? = nil) {
guard let viewControllerToPresentFrom = viewControllerToPresentFrom else { return }
self.interactive = interactive
func present(_ viewControllerToPresentFrom: UIViewController?, interactively: Bool, completion: (() -> Void)? = nil) {
guard let viewControllerToPresentFrom = viewControllerToPresentFrom, transitioningDelegate != nil else { return }
transitionController?.interactive = interactively
viewControllerToPresentFrom.present(self, animated: true, completion: completion)
}
}
private extension UISideMenuNavigationController {
private extension SideMenuNavigationController {
func shouldPushViewController(viewController: UIViewController, animated: Bool, completion: ((Bool) -> Void)?) -> Bool {
guard viewControllers.count > 0 && pushStyle != .subMenu else {
// NOTE: pushViewController is called by init(rootViewController: UIViewController)
// so we must perform the normal super method in this case
return true
}
let splitViewController = presentingViewController as? UISplitViewController
let tabBarController = presentingViewController as? UITabBarController
let potentialNavigationController = (splitViewController?.viewControllers.first ?? tabBarController?.selectedViewController) ?? presentingViewController
guard let navigationController = potentialNavigationController as? UINavigationController else {
Print.warning(.cannotPush, arguments: String(describing: potentialNavigationController.self), required: true)
return false
}
// To avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
// is dismissed after showing the appropriate screen
CATransaction.begin()
defer { CATransaction.commit() }
var push = false
if dismissOnPush {
let animated = animated || alwaysAnimate
if animated {
let areAnimationsEnabled = UIView.areAnimationsEnabled
UIView.setAnimationsEnabled(true)
transitionController?.transition(presenting: false, animated: animated, alongsideTransition: { [weak self] in
guard let self = self else { return }
self.activeDelegate?.sideMenuWillDisappear?(menu: self, animated: animated)
}, completion: { [weak self] _ in
guard let self = self else { return }
self.activeDelegate?.sideMenuDidDisappear?(menu: self, animated: animated)
self.dismiss(animated: false, completion: nil)
completion?(push)
})
UIView.setAnimationsEnabled(areAnimationsEnabled)
}
}
if let lastViewController = navigationController.viewControllers.last,
!allowPushOfSameClassTwice && type(of: lastViewController) == type(of: viewController) {
return false
}
switch pushStyle {
case .subMenu: return false // handled earlier
case .default:
navigationController.pushViewController(viewController, animated: animated)
return false
case .popWhenPossible:
for subViewController in navigationController.viewControllers.reversed() {
if type(of: subViewController) == type(of: viewController) {
navigationController.popToViewController(subViewController, animated: animated)
return false
}
}
push = true
return true
case .preserve, .preserveAndHideBackButton:
var viewControllers = navigationController.viewControllers
let filtered = viewControllers.filter { preservedViewController in type(of: preservedViewController) == type(of: viewController) }
if let preservedViewController = filtered.last {
viewControllers = viewControllers.filter { subViewController in subViewController !== preservedViewController }
if pushStyle == .preserveAndHideBackButton {
preservedViewController.navigationItem.hidesBackButton = true
}
viewControllers.append(preservedViewController)
navigationController.setViewControllers(viewControllers, animated: animated)
return false
}
if pushStyle == .preserveAndHideBackButton {
viewController.navigationItem.hidesBackButton = true
}
push = true
return true
case .replace:
viewController.navigationItem.hidesBackButton = true
navigationController.setViewControllers([viewController], animated: animated)
return false
}
}
private class func elseCondition(_ propertyName: PropertyName) {
Print.warning(.property, arguments: propertyName.rawValue, required: true)
}
weak var activeDelegate: UISideMenuNavigationControllerDelegate? {
weak var activeDelegate: SideMenuNavigationControllerDelegate? {
guard !view.isHidden else { return nil }
return sideMenuDelegate ?? foundDelegate ?? findDelegate(forViewController: presentingViewController)
if let sideMenuDelegate = sideMenuDelegate { return sideMenuDelegate }
return findViewController as? SideMenuNavigationControllerDelegate
}
func findDelegate(forViewController: UIViewController?) -> UISideMenuNavigationControllerDelegate? {
if let navigationController = forViewController as? UINavigationController {
return findDelegate(forViewController: navigationController.topViewController)
}
if let tabBarController = forViewController as? UITabBarController {
return findDelegate(forViewController: tabBarController.selectedViewController)
}
if let splitViewController = forViewController as? UISplitViewController {
return findDelegate(forViewController: splitViewController.viewControllers.last)
}
var findViewController: UIViewController? {
foundViewController = foundViewController ?? presentingViewController?.activeViewController
return foundViewController
}
foundDelegate = forViewController as? UISideMenuNavigationControllerDelegate
return foundDelegate
func dismissAnimation(animated: Bool) {
transitionController?.transition(presenting: false, animated: animated, alongsideTransition: { [weak self] in
guard let self = self else { return }
self.activeDelegate?.sideMenuWillDisappear?(menu: self, animated: animated)
}, completion: { [weak self] _ in
guard let self = self else { return }
self.activeDelegate?.sideMenuDidDisappear?(menu: self, animated: animated)
self.dismiss(animated: false, completion: nil)
self.foundViewController = nil
})
}
func setup() {
modalPresentationStyle = .overFullScreen
setupBlur()
setupSwipeGestures()
registerForNotifications()
if #available(iOS 13.0, *) {} else {
registerForNotifications()
}
}
func setupBlur() {
@@ -631,24 +591,17 @@ private extension UISideMenuNavigationController {
}
}
func setupSwipeGestures() {
if let swipeToDismissGesture = swipeToDismissGesture {
swipeToDismissGesture.view?.removeGestureRecognizer(swipeToDismissGesture)
}
if enableSwipeGestures {
swipeToDismissGesture = addDismissPanGesture(to: view)
}
}
@available(iOS, deprecated: 13.0)
func registerForNotifications() {
NotificationCenter.default.removeObserver(self)
[UIApplication.willChangeStatusBarFrameNotification,
UIApplication.didEnterBackgroundNotification].forEach {
UIApplication.didEnterBackgroundNotification].forEach {
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: $0, object: nil)
}
}
@available(iOS, deprecated: 13.0)
@objc func handleNotification(notification: NSNotification) {
guard isHidden else { return }
@@ -666,16 +619,23 @@ private extension UISideMenuNavigationController {
}
}
@discardableResult func addDismissPanGesture(to view: UIView) -> UIPanGestureRecognizer {
return UIPanGestureRecognizer {
@discardableResult func addSwipeToDismissGesture(to view: UIView?) -> UIPanGestureRecognizer? {
guard enableSwipeToDismissGesture else { return nil }
return UIPanGestureRecognizer(addTo: view, target: self, action: #selector(handleDismissMenuPan(_:)))?.with {
$0.cancelsTouchesInView = false
}
}
@discardableResult func addTapToDismissGesture(to view: UIView?) -> UITapGestureRecognizer? {
guard enableTapToDismissGesture else { return nil }
return UITapGestureRecognizer(addTo: view, target: self, action: #selector(handleDismissMenuTap(_:)))?.with {
$0.cancelsTouchesInView = false
$0.addTarget(self, action: #selector(handleDismissMenuPan(_:)))
view.addGestureRecognizer($0)
}
}
@objc func handleDismissMenuTap(_ tap: UITapGestureRecognizer) {
guard view.window?.hitTest(tap.location(in: nil), with: nil) == view.superview else { return }
let hitTest = view.window?.hitTest(tap.location(in: view.superview), with: nil)
guard hitTest == view.superview else { return }
dismissMenu()
}
@@ -7,6 +7,19 @@
import UIKit
internal protocol PresentationModel {
/// Draws `presentStyle.backgroundColor` behind the status bar. Default is 1.
var statusBarEndAlpha: CGFloat { get }
/// Enable or disable interaction with the presenting view controller while the menu is displayed. Enabling may make it difficult to dismiss the menu or cause exceptions if the user tries to present and already presented menu. `presentingViewControllerUseSnapshot` must also set to false. Default is false.
var presentingViewControllerUserInteractionEnabled: Bool { get }
/// Use a snapshot for the presenting vierw controller while the menu is displayed. Useful when layout changes occur during transitions. Not recommended for apps that support rotation. Default is false.
var presentingViewControllerUseSnapshot: Bool { get }
/// The presentation style of the menu.
var presentationStyle: SideMenuPresentationStyle { get }
/// Width of the menu when presented on screen, showing the existing view controller in the remaining space. Default is zero.
var menuWidth: CGFloat { get }
}
internal protocol SideMenuPresentationControllerDelegate: class {
func sideMenuPresentationControllerDidTap(_ presentationController: SideMenuPresentationController)
func sideMenuPresentationController(_ presentationController: SideMenuPresentationController, didPanWith gesture: UIPanGestureRecognizer)
@@ -17,6 +30,7 @@ internal final class SideMenuPresentationController {
private let config: PresentationModel
private unowned var containerView: UIView
private var interactivePopGestureRecognizerEnabled: Bool?
private var clipsToBounds: Bool?
private let leftSide: Bool
private weak var originalSuperview: UIView?
private unowned var presentedViewController: UIViewController
@@ -77,7 +91,12 @@ internal final class SideMenuPresentationController {
guard let statusBarView = statusBarView else { return }
let statusBarOffset = containerView.frame.size.height - presentedViewController.view.bounds.height
var statusBarFrame = UIApplication.shared.statusBarFrame
var statusBarFrame: CGRect
if #available(iOS 13.0, *) {
statusBarFrame = containerView.window?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
} else {
statusBarFrame = UIApplication.shared.statusBarFrame
}
// For in-call status bar, height is normally 40, which overlaps view. Instead, calculate height difference
// of view and set height to fill in remaining space.
@@ -172,9 +191,7 @@ internal final class SideMenuPresentationController {
statusBarView?.removeFromSuperview()
presentedViewController.view.removeFromSuperview()
presentingViewController.view.motionEffects.removeAll()
presentingViewController.view.layer.shadowOpacity = 0
presentedViewController.view.layer.shadowOpacity = 0
removeStyles(from: presentingViewController.containerViewController.view)
if let interactivePopGestureRecognizerEnabled = interactivePopGestureRecognizerEnabled,
let topNavigationController = presentingViewController as? UINavigationController {
@@ -211,11 +228,9 @@ private extension SideMenuPresentationController {
if config.presentationStyle.menuOnTop {
addShadow(to: presentedViewController.view)
presentedViewController.view.layer.zPosition = 1
presentingViewController.view.layer.zPosition = 0
} else {
addShadow(to: presentingViewController.view)
presentingViewController.view.layer.zPosition = 1
presentedViewController.view.layer.zPosition = 0
presentedViewController.view.layer.zPosition = -1
}
}
@@ -223,7 +238,9 @@ private extension SideMenuPresentationController {
view.layer.shadowColor = config.presentationStyle.onTopShadowColor.cgColor
view.layer.shadowRadius = config.presentationStyle.onTopShadowRadius
view.layer.shadowOpacity = config.presentationStyle.onTopShadowOpacity
view.layer.shadowOffset = CGSize(width: 0, height: 0)
view.layer.shadowOffset = config.presentationStyle.onTopShadowOffset
clipsToBounds = clipsToBounds ?? view.clipsToBounds
view.clipsToBounds = false
}
func addParallax(to view: UIView) {
@@ -252,4 +269,12 @@ private extension SideMenuPresentationController {
view.addMotionEffect(group)
}
}
func removeStyles(from view: UIView) {
view.motionEffects.removeAll()
view.layer.shadowOpacity = 0
view.layer.shadowOpacity = 0
view.clipsToBounds = clipsToBounds ?? true
clipsToBounds = false
}
}
+3 -8
View File
@@ -5,10 +5,10 @@
// Created by Jon Kent on 7/2/19.
//
import Foundation
import UIKit
@objcMembers
public class SideMenuPresentationStyle {
open class SideMenuPresentationStyle: InitializableClass {
/// Background color behind the views and status bar color
public var backgroundColor: UIColor = .black
/// The starting alpha value of the menu before it appears
@@ -36,12 +36,7 @@ public class SideMenuPresentationStyle {
/// The strength of the parallax effect on the presenting view once the menu is displayed.
public var presentingParallaxStrength: CGSize = .zero
public init() {}
public convenience init(_ block: (SideMenuPresentationStyle) -> Void) {
self.init()
block(self)
}
required public init() {}
/// This method is called just before the presentation transition begins. Use this to setup any animations. The super method does not need to be called.
func presentationTransitionWillBegin(to presentedViewController: UIViewController, from presentingViewController: UIViewController) {}
+107
View File
@@ -0,0 +1,107 @@
//
// PushCoordinator.swift
// SideMenu
//
// Created by Jon Kent on 9/4/19.
//
import UIKit
protocol CoordinatorModel {
var animated: Bool { get }
var fromViewController: UIViewController { get }
var toViewController: UIViewController { get }
}
protocol Coordinator {
associatedtype Model: CoordinatorModel
init(config: Model)
@discardableResult func start() -> Bool
}
internal final class SideMenuPushCoordinator: Coordinator {
struct Model: CoordinatorModel {
var allowPushOfSameClassTwice: Bool
var alongsideTransition: (() -> Void)?
var animated: Bool
var fromViewController: UIViewController
var pushStyle: SideMenuPushStyle
var toViewController: UIViewController
}
private let config: Model
init(config: Model) {
self.config = config
}
@discardableResult func start() -> Bool {
guard config.pushStyle != .subMenu,
let fromNavigationController = config.fromViewController as? UINavigationController else {
return false
}
let toViewController = config.toViewController
let presentingViewController = fromNavigationController.presentingViewController
let splitViewController = presentingViewController as? UISplitViewController
let tabBarController = presentingViewController as? UITabBarController
let potentialNavigationController = (splitViewController?.viewControllers.first ?? tabBarController?.selectedViewController) ?? presentingViewController
guard let navigationController = potentialNavigationController as? UINavigationController else {
Print.warning(.cannotPush, arguments: String(describing: potentialNavigationController.self), required: true)
return false
}
// To avoid overlapping dismiss & pop/push calls, create a transaction block where the menu
// is dismissed after showing the appropriate screen
CATransaction.begin()
defer { CATransaction.commit() }
UIView.animationsEnabled { [weak self] in
self?.config.alongsideTransition?()
}
if let lastViewController = navigationController.viewControllers.last,
!config.allowPushOfSameClassTwice && type(of: lastViewController) == type(of: toViewController) {
return false
}
toViewController.navigationItem.hidesBackButton = config.pushStyle.hidesBackButton
switch config.pushStyle {
case .default:
navigationController.pushViewController(toViewController, animated: config.animated)
return true
// subMenu handled earlier
case .subMenu:
return false
case .popWhenPossible:
for subViewController in navigationController.viewControllers.reversed() {
if type(of: subViewController) == type(of: toViewController) {
navigationController.popToViewController(subViewController, animated: config.animated)
return true
}
}
navigationController.pushViewController(toViewController, animated: config.animated)
return true
case .preserve, .preserveAndHideBackButton:
var viewControllers = navigationController.viewControllers
let filtered = viewControllers.filter { preservedViewController in type(of: preservedViewController) == type(of: toViewController) }
guard let preservedViewController = filtered.last else {
navigationController.pushViewController(toViewController, animated: config.animated)
return true
}
viewControllers = viewControllers.filter { subViewController in subViewController !== preservedViewController }
viewControllers.append(preservedViewController)
navigationController.setViewControllers(viewControllers, animated: config.animated)
return true
case .replace:
navigationController.setViewControllers([toViewController], animated: config.animated)
return true
}
}
}
+58 -152
View File
@@ -1,8 +1,9 @@
//
// SideMenuAnimationController.swift
// SideMenuTransitioningDelegate.swift
// SideMenu
//
// Created by Jon Kent on 10/24/18.
// Created by Jon Kent on 8/29/19.
// Copyright © 2019 jonkykong. All rights reserved.
//
import UIKit
@@ -12,176 +13,81 @@ internal protocol SideMenuTransitionControllerDelegate: class {
func sideMenuTransitionController(_ transitionController: SideMenuTransitionController, didPresent viewController: UIViewController)
}
internal final class SideMenuTransitionController: NSObject, UIViewControllerAnimatedTransitioning {
internal final class SideMenuTransitionController: NSObject, UIViewControllerTransitioningDelegate {
typealias Model = MenuModel & AnimationModel & PresentationModel
private var config: TransitionModel
private weak var containerView: UIView?
private let leftSide: Bool
private var presentationController: SideMenuPresentationController!
private unowned var presentedViewController: UIViewController?
private unowned var presentingViewController: UIViewController?
private let config: Model
private var animationController: SideMenuAnimationController?
private weak var interactionController: SideMenuInteractionController?
var interactive: Bool = false
weak var delegate: SideMenuTransitionControllerDelegate?
init(config: TransitionModel, leftSide: Bool, delegate: SideMenuTransitionControllerDelegate? = nil) {
self.config = config
init(leftSide: Bool, config: Model) {
self.leftSide = leftSide
self.delegate = delegate
self.config = config
super.init()
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard
let presentedViewController = transitionContext.presentedViewController,
let presentingViewController = transitionContext.presentingViewController
else { return }
if transitionContext.isPresenting {
self.containerView = transitionContext.containerView
self.presentedViewController = presentedViewController
self.presentingViewController = presentingViewController
self.presentationController = SideMenuPresentationController(
config: config,
leftSide: leftSide,
presentedViewController: presentedViewController,
presentingViewController: presentingViewController,
containerView: transitionContext.containerView
)
}
transition(using: transitionContext)
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
animationController = SideMenuAnimationController(
config: config,
leftSide: leftSide,
delegate: self)
return animationController
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
guard let transitionContext = transitionContext else { return 0 }
return duration(presenting: transitionContext.isPresenting, interactive: transitionContext.isInteractive)
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return animationController
}
func animationEnded(_ transitionCompleted: Bool) {
guard let presentedViewController = presentedViewController else { return }
if presentedViewController.isHidden {
delegate?.sideMenuTransitionController(self, didDismiss: presentedViewController)
} else {
delegate?.sideMenuTransitionController(self, didPresent: presentedViewController)
}
func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController(using: animator)
}
func transition(presenting: Bool, animated: Bool = true, interactive: Bool = false, alongsideTransition: (() -> Void)? = nil, complete: Bool = true, completion: ((Bool) -> Void)? = nil) {
transitionWillBegin(presenting: presenting)
transition(presenting: presenting,
animated: animated,
interactive: interactive,
animations: { [weak self] in
guard let self = self else { return }
self.transition(presenting: presenting)
alongsideTransition?()
}, completion: { [weak self] _ in
guard let self = self else { return }
if complete {
self.transitionDidEnd(presenting: presenting, completed: true)
}
completion?(true)
})
func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return interactionController(using: animator)
}
internal func handle(state: SideMenuInteractionController.State) {
interactionController?.handle(state: state)
}
func layout() {
presentationController.containerViewWillLayoutSubviews()
animationController?.layout()
}
func transition(presenting: Bool, animated: Bool = true, interactive: Bool = false, alongsideTransition: (() -> Void)? = nil, complete: Bool = true, completion: ((Bool) -> Void)? = nil) {
animationController?.transition(
presenting: presenting,
animated: animated,
interactive: interactive,
alongsideTransition: alongsideTransition,
complete: complete, completion: completion
)
}
}
extension SideMenuTransitionController: SideMenuAnimationControllerDelegate {
internal func sideMenuAnimationController(_ animationController: SideMenuAnimationController, didDismiss viewController: UIViewController) {
delegate?.sideMenuTransitionController(self, didDismiss: viewController)
}
internal func sideMenuAnimationController(_ animationController: SideMenuAnimationController, didPresent viewController: UIViewController) {
delegate?.sideMenuTransitionController(self, didPresent: viewController)
}
}
private extension SideMenuTransitionController {
func duration(presenting: Bool, interactive: Bool) -> Double {
if interactive { return config.completeGestureDuration }
return presenting ? config.presentDuration : config.dismissDuration
}
func transitionWillBegin(presenting: Bool) {
// prevent any other menu gestures from firing
containerView?.isUserInteractionEnabled = false
if presenting {
presentationController.presentationTransitionWillBegin()
} else {
presentationController.dismissalTransitionWillBegin()
}
}
func transition(presenting: Bool) {
if presenting {
presentationController.presentationTransition()
} else {
presentationController.dismissalTransition()
}
}
func transitionDidEnd(presenting: Bool, completed: Bool) {
if presenting {
presentationController.presentationTransitionDidEnd(completed)
} else {
presentationController.dismissalTransitionDidEnd(completed)
}
containerView?.isUserInteractionEnabled = true
}
func transition(using transitionContext: UIViewControllerContextTransitioning) {
transitionWillBegin(presenting: transitionContext.isPresenting)
transition(presenting: transitionContext.isPresenting,
animated: transitionContext.isAnimated,
interactive: transitionContext.isInteractive,
animations: { [weak self] in
guard let self = self else { return }
self.transition(presenting: transitionContext.isPresenting)
}, completion: { [weak self] _ in
guard let self = self else { return }
let completed = !transitionContext.transitionWasCancelled
self.transitionDidEnd(presenting: transitionContext.isPresenting, completed: completed)
transitionContext.completeTransition(completed)
})
}
func transition(presenting: Bool, animated: Bool = true, interactive: Bool = false, animations: @escaping (() -> Void) = {}, completion: @escaping ((Bool) -> Void) = { _ in }) {
if !animated {
animations()
completion(true)
return
}
let duration = self.duration(presenting: presenting, interactive: interactive)
if interactive {
// IMPORTANT: The non-interactive animation block will not complete if adapted for interactive. The below animation block must be used!
UIView.animate(
withDuration: duration,
delay: duration, // HACK: If zero, the animation briefly flashes in iOS 11.
options: .curveLinear,
animations: animations,
completion: completion
)
return
}
UIView.animate(
withDuration: duration,
delay: 0,
usingSpringWithDamping: config.usingSpringWithDamping,
initialSpringVelocity: config.initialSpringVelocity,
options: config.animationOptions,
animations: animations,
completion: completion
)
}
}
private extension UIViewControllerContextTransitioning {
var isPresenting: Bool {
return viewController(forKey: .from)?.presentedViewController === viewController(forKey: .to)
}
var presentingViewController: UIViewController? {
return viewController(forKey: isPresenting ? .from : .to)
}
var presentedViewController: UIViewController? {
return viewController(forKey: isPresenting ? .to : .from)
func interactionController(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
guard interactive else { return nil }
interactive = false
let interactionController = SideMenuInteractionController(cancelWhenBackgrounded: config.dismissWhenBackgrounded, completionCurve: config.completionCurve)
self.interactionController = interactionController
return interactionController
}
}
+3 -3
View File
@@ -10,9 +10,9 @@ import UIKit
open class UITableViewVibrantCell: UITableViewCell {
private var vibrancyView:UIVisualEffectView = UIVisualEffectView()
private var vibrancySelectedBackgroundView:UIVisualEffectView = UIVisualEffectView()
private var defaultSelectedBackgroundView:UIView?
private var vibrancyView: UIVisualEffectView = UIVisualEffectView()
private var vibrancySelectedBackgroundView: UIVisualEffectView = UIVisualEffectView()
private var defaultSelectedBackgroundView: UIView?
open var blurEffectStyle: UIBlurEffect.Style? {
didSet {
updateBlur()
+2 -2
View File
@@ -1,5 +1,5 @@
PODS:
- SideMenu (6.0.0)
- SideMenu (6.2.5)
DEPENDENCIES:
- SideMenu (from `.`)
@@ -9,7 +9,7 @@ EXTERNAL SOURCES:
:path: "."
SPEC CHECKSUMS:
SideMenu: 1b826b95cc7db1a3c7d164f8a6e6e92506ffb0f5
SideMenu: cba46f5cd6080a0e38137d5be285e8bcf0f36eb4
PODFILE CHECKSUM: 863f183ea1ab6f64dc8553590349c586faf8e4a1
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "SideMenu",
"version": "6.0.0",
"version": "6.2.5",
"summary": "Simple side menu control for iOS 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",
@@ -19,12 +19,12 @@
},
"source": {
"git": "https://github.com/jonkykong/SideMenu.git",
"tag": "6.0.0"
"tag": "6.2.5"
},
"platforms": {
"ios": "10.0"
},
"swift_versions": "5",
"swift_versions": "5.0",
"source_files": "Pod/Classes/**/*",
"swift_version": "5"
"swift_version": "5.0"
}
+2 -2
View File
@@ -1,5 +1,5 @@
PODS:
- SideMenu (6.0.0)
- SideMenu (6.2.5)
DEPENDENCIES:
- SideMenu (from `.`)
@@ -9,7 +9,7 @@ EXTERNAL SOURCES:
:path: "."
SPEC CHECKSUMS:
SideMenu: 1b826b95cc7db1a3c7d164f8a6e6e92506ffb0f5
SideMenu: cba46f5cd6080a0e38137d5be285e8bcf0f36eb4
PODFILE CHECKSUM: 863f183ea1ab6f64dc8553590349c586faf8e4a1
+216 -197
View File
@@ -7,24 +7,25 @@
objects = {
/* Begin PBXBuildFile section */
032FEB01E4C88E7C87032FCF9780FC7C /* UISideMenuNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F8B09C72B577EFDB20A3EFF4F0C668A /* UISideMenuNavigationController.swift */; };
0D2D410A6087D4E0A54642165913EF30 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F10B146FA49E99D07F0FA0E38ABE8F /* Models.swift */; };
0F9F3CABB81269CF711A73BAD21E7976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; };
287FA1360FD3EF72D700C54856C685C1 /* SideMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FE7B8C8447DD35D435B2AF4A23E221C /* SideMenuManager.swift */; };
31E79D7BA42208D00E73C18CBAF1598E /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B25193EDCA447F119795F68F75BF05 /* Extensions.swift */; };
384CBA8850C8BF3A7AAB3A3D78844B1E /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13846826E721392191757B9033D6F63F /* Protected.swift */; };
45A647715262A70BB9F2F4E7C1439C58 /* UITableViewVibrantCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ACA278071ED85D04DA83677D6C60528 /* UITableViewVibrantCell.swift */; };
5B0A5C9933D0FCD08E12CFFB56145333 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */; };
614FC39555CB129D97FC24B2D953A427 /* SideMenuPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61AFB3209BCB97295281AC6437FB346B /* SideMenuPresentationController.swift */; };
6E6E17C0E8351D23CB4B20332C70BE61 /* Print.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CB39D726F07EA27650309A1A3213412 /* Print.swift */; };
849F7B5B2320FCC6005DEB6A /* SideMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 849F7B562320F3A4005DEB6A /* SideMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
849F7B5E2320FD67005DEB6A /* SideMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 849F7B562320F3A4005DEB6A /* SideMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
849F7B7123210C6E005DEB6A /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B6C23210C6E005DEB6A /* Deprecations.swift */; };
849F7B7223210C6E005DEB6A /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B6D23210C6E005DEB6A /* Extensions.swift */; };
849F7B7323210C6E005DEB6A /* Initializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B6E23210C6E005DEB6A /* Initializable.swift */; };
849F7B7423210C6E005DEB6A /* Print.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B6F23210C6E005DEB6A /* Print.swift */; };
849F7B7523210C6E005DEB6A /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7023210C6E005DEB6A /* Protected.swift */; };
849F7B7F23210C79005DEB6A /* SideMenuNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7623210C79005DEB6A /* SideMenuNavigationController.swift */; };
849F7B8023210C79005DEB6A /* SideMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7723210C79005DEB6A /* SideMenuManager.swift */; };
849F7B8123210C79005DEB6A /* SideMenuPresentationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7823210C79005DEB6A /* SideMenuPresentationStyle.swift */; };
849F7B8223210C79005DEB6A /* SideMenuInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7923210C79005DEB6A /* SideMenuInteractionController.swift */; };
849F7B8323210C79005DEB6A /* SideMenuPushCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7A23210C79005DEB6A /* SideMenuPushCoordinator.swift */; };
849F7B8423210C79005DEB6A /* SideMenuAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7B23210C79005DEB6A /* SideMenuAnimationController.swift */; };
849F7B8523210C79005DEB6A /* SideMenuTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7C23210C79005DEB6A /* SideMenuTransitionController.swift */; };
849F7B8623210C79005DEB6A /* UITableViewVibrantCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7D23210C79005DEB6A /* UITableViewVibrantCell.swift */; };
849F7B8723210C79005DEB6A /* SideMenuPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B7E23210C79005DEB6A /* SideMenuPresentationController.swift */; };
89B2CFA98A07964FBD2D7775FF5FB98D /* Pods-Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D6D7C498FA339E02BD53ECB8916CEA8E /* Pods-Example-dummy.m */; };
A2ACFE2D997BC8F1DA4EE3064A4270DD /* SideMenuInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB64592703EA9A196B5C0F07BA1A918A /* SideMenuInteractionController.swift */; };
BD5C0C12B6BB0BF6DA294E095B35E38D /* Initializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00F847D27577EF5335081BFA43A0BFA3 /* Initializable.swift */; };
D0B45D0F0E7B359807CAFB744FB80CE4 /* SideMenuPresentationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D154DB98A04C7BD96E4EFBBD3FE0008A /* SideMenuPresentationStyle.swift */; };
D7BD58D0FF7BF7E887B6D70D4651D70B /* Pods-Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7825A90E082A1582EB16256B0E722B3F /* Pods-Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA6F42990A37DF6179D6386008BB87F8 /* SideMenu-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 36C5772477B00653D86343BABD123EF3 /* SideMenu-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
F1967413D21BCA08963F09969D47E152 /* SideMenu-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF977D7FB42D367F2810037EBA59B7D /* SideMenu-dummy.m */; };
FCBFE25630B6309DF3213AE0F6F34D1A /* SideMenuTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C3188EE68841BE36716860BE079AF8 /* SideMenuTransitionController.swift */; };
D7BD58D0FF7BF7E887B6D70D4651D70B /* Pods-Example.h in Headers */ = {isa = PBXBuildFile; fileRef = 7825A90E082A1582EB16256B0E722B3F /* Pods-Example.h */; settings = {ATTRIBUTES = (Public, ); }; };
E6F2CD13BC297BF5E7707DEDE9C7F271 /* SideMenu-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DF9702572C0E4370367755578F2ECE7 /* SideMenu-dummy.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -38,40 +39,41 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
00F847D27577EF5335081BFA43A0BFA3 /* Initializable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Initializable.swift; path = Pod/Classes/Initializable.swift; sourceTree = "<group>"; };
0FD529BD299167F85338CB5BB3463BED /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = "<group>"; };
105D784922AF9F627D902729C7D0E3CA /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = "<group>"; };
13846826E721392191757B9033D6F63F /* Protected.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Pod/Classes/Protected.swift; sourceTree = "<group>"; };
1D01FD908F7943A6131CA6F66DD0CA68 /* SideMenu-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SideMenu-Info.plist"; sourceTree = "<group>"; };
1F667CC0E19EAF34E5A4119E2121F585 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Example.framework; path = "Pods-Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
1FE7B8C8447DD35D435B2AF4A23E221C /* SideMenuManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SideMenuManager.swift; path = Pod/Classes/SideMenuManager.swift; sourceTree = "<group>"; };
1F667CC0E19EAF34E5A4119E2121F585 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
243410B9535472556EA4BB6DBC133A0D /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
2CB39D726F07EA27650309A1A3213412 /* Print.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Print.swift; path = Pod/Classes/Print.swift; sourceTree = "<group>"; };
30C3188EE68841BE36716860BE079AF8 /* SideMenuTransitionController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SideMenuTransitionController.swift; path = Pod/Classes/SideMenuTransitionController.swift; sourceTree = "<group>"; };
319D06AA0D1D0BA345459C039040A1ED /* SideMenu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SideMenu.framework; path = SideMenu.framework; sourceTree = BUILT_PRODUCTS_DIR; };
319D06AA0D1D0BA345459C039040A1ED /* SideMenu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SideMenu.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31C1D37707DFAA5E6A164BCC07834264 /* Pods-Example-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Example-Info.plist"; sourceTree = "<group>"; };
3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
35C305D3797C284E6F5BAA1D3E6F9BF8 /* Pods-Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Example.modulemap"; sourceTree = "<group>"; };
36C5772477B00653D86343BABD123EF3 /* SideMenu-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SideMenu-umbrella.h"; sourceTree = "<group>"; };
3ACA278071ED85D04DA83677D6C60528 /* UITableViewVibrantCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UITableViewVibrantCell.swift; path = Pod/Classes/UITableViewVibrantCell.swift; sourceTree = "<group>"; };
441854E35F81731E63E53DC7E4EEAD9D /* Pods-Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Example-acknowledgements.markdown"; sourceTree = "<group>"; };
61AFB3209BCB97295281AC6437FB346B /* SideMenuPresentationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SideMenuPresentationController.swift; path = Pod/Classes/SideMenuPresentationController.swift; sourceTree = "<group>"; };
7825A90E082A1582EB16256B0E722B3F /* Pods-Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Example-umbrella.h"; sourceTree = "<group>"; };
8F8B09C72B577EFDB20A3EFF4F0C668A /* UISideMenuNavigationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UISideMenuNavigationController.swift; path = Pod/Classes/UISideMenuNavigationController.swift; sourceTree = "<group>"; };
9CF977D7FB42D367F2810037EBA59B7D /* SideMenu-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SideMenu-dummy.m"; sourceTree = "<group>"; };
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
AB64592703EA9A196B5C0F07BA1A918A /* SideMenuInteractionController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SideMenuInteractionController.swift; path = Pod/Classes/SideMenuInteractionController.swift; sourceTree = "<group>"; };
4DF9702572C0E4370367755578F2ECE7 /* SideMenu-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SideMenu-dummy.m"; sourceTree = "<group>"; };
5B30AFEB50A77ED133026BBB542D4DC2 /* SideMenu-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SideMenu-Info.plist"; sourceTree = "<group>"; };
5F375DA230E88A457A5F6021E054F56D /* SideMenu.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SideMenu.xcconfig; sourceTree = "<group>"; };
7825A90E082A1582EB16256B0E722B3F /* Pods-Example.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Example.h"; sourceTree = "<group>"; };
849F7B562320F3A4005DEB6A /* SideMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SideMenu.h; sourceTree = "<group>"; };
849F7B6C23210C6E005DEB6A /* Deprecations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Deprecations.swift; path = Pod/Classes/Deprecations.swift; sourceTree = "<group>"; };
849F7B6D23210C6E005DEB6A /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = Pod/Classes/Extensions.swift; sourceTree = "<group>"; };
849F7B6E23210C6E005DEB6A /* Initializable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Initializable.swift; path = Pod/Classes/Initializable.swift; sourceTree = "<group>"; };
849F7B6F23210C6E005DEB6A /* Print.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Print.swift; path = Pod/Classes/Print.swift; sourceTree = "<group>"; };
849F7B7023210C6E005DEB6A /* Protected.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Pod/Classes/Protected.swift; sourceTree = "<group>"; };
849F7B7623210C79005DEB6A /* SideMenuNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuNavigationController.swift; path = Pod/Classes/SideMenuNavigationController.swift; sourceTree = "<group>"; };
849F7B7723210C79005DEB6A /* SideMenuManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuManager.swift; path = Pod/Classes/SideMenuManager.swift; sourceTree = "<group>"; };
849F7B7823210C79005DEB6A /* SideMenuPresentationStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuPresentationStyle.swift; path = Pod/Classes/SideMenuPresentationStyle.swift; sourceTree = "<group>"; };
849F7B7923210C79005DEB6A /* SideMenuInteractionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuInteractionController.swift; path = Pod/Classes/SideMenuInteractionController.swift; sourceTree = "<group>"; };
849F7B7A23210C79005DEB6A /* SideMenuPushCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuPushCoordinator.swift; path = Pod/Classes/SideMenuPushCoordinator.swift; sourceTree = "<group>"; };
849F7B7B23210C79005DEB6A /* SideMenuAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuAnimationController.swift; path = Pod/Classes/SideMenuAnimationController.swift; sourceTree = "<group>"; };
849F7B7C23210C79005DEB6A /* SideMenuTransitionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuTransitionController.swift; path = Pod/Classes/SideMenuTransitionController.swift; sourceTree = "<group>"; };
849F7B7D23210C79005DEB6A /* UITableViewVibrantCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UITableViewVibrantCell.swift; path = Pod/Classes/UITableViewVibrantCell.swift; sourceTree = "<group>"; };
849F7B7E23210C79005DEB6A /* SideMenuPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuPresentationController.swift; path = Pod/Classes/SideMenuPresentationController.swift; sourceTree = "<group>"; };
863A19DF8C4FEFD1D2DFF3C6C85F3013 /* SideMenu-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SideMenu-prefix.pch"; sourceTree = "<group>"; };
89DDCB61CB91FEE47235E0C0915F9F88 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
9A5090CE306074592C68F6FB7ADF43FA /* SideMenu.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SideMenu.modulemap; sourceTree = "<group>"; };
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
AFECBC24E09D0D25F822C27BD944AFD4 /* Pods-Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Example-frameworks.sh"; sourceTree = "<group>"; };
B45138496B85A072654D1D0F8EBBEDE5 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
B5F10B146FA49E99D07F0FA0E38ABE8F /* Models.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Models.swift; path = Pod/Classes/Models.swift; sourceTree = "<group>"; };
BB1EC6DFBB713FC2F280D596714173EC /* SideMenu.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SideMenu.xcconfig; sourceTree = "<group>"; };
BD4CEC04022777F53C1CA2113A43FACE /* SideMenu-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SideMenu-prefix.pch"; sourceTree = "<group>"; };
BE262D79CAE897127A1984945DCE9FEE /* SideMenu.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = SideMenu.podspec; sourceTree = "<group>"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
D154DB98A04C7BD96E4EFBBD3FE0008A /* SideMenuPresentationStyle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SideMenuPresentationStyle.swift; path = Pod/Classes/SideMenuPresentationStyle.swift; sourceTree = "<group>"; };
BE3D03F947820C757C6A1858FE0784C9 /* SideMenu.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = SideMenu.podspec; sourceTree = "<group>"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
D6D7C498FA339E02BD53ECB8916CEA8E /* Pods-Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Example-dummy.m"; sourceTree = "<group>"; };
E656C89A7C466C66F803FC806E30B29E /* SideMenu.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SideMenu.modulemap; sourceTree = "<group>"; };
EA21B344259B58996DB73382B1B1521F /* Pods-Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Example-acknowledgements.plist"; sourceTree = "<group>"; };
F1B25193EDCA447F119795F68F75BF05 /* Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = Pod/Classes/Extensions.swift; sourceTree = "<group>"; };
F2868E435B4FF74B943FC555CA3271AA /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -79,15 +81,13 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0F9F3CABB81269CF711A73BAD21E7976 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B55A7DF9A704D60A5DE58A98398D7779 /* Frameworks */ = {
D530FD6E7F0D492D9036605CB47EAB59 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5B0A5C9933D0FCD08E12CFFB56145333 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -103,14 +103,50 @@
name = Products;
sourceTree = "<group>";
};
71A499AE33E397EBD7FA1A9D5B8440BA /* Pod */ = {
0D8598CC67DCD15FA8FD2571BFA1FDD0 /* Development Pods */ = {
isa = PBXGroup;
children = (
105D784922AF9F627D902729C7D0E3CA /* LICENSE */,
0FD529BD299167F85338CB5BB3463BED /* README.md */,
BE262D79CAE897127A1984945DCE9FEE /* SideMenu.podspec */,
15941242C0946F16AAC2EA37A208D559 /* SideMenu */,
);
name = Pod;
name = "Development Pods";
sourceTree = "<group>";
};
15941242C0946F16AAC2EA37A208D559 /* SideMenu */ = {
isa = PBXGroup;
children = (
B9E764EFCD0B407437AC1550B5A6FB28 /* Pod */,
F2C813E2A0676FE71DB8D655549E2635 /* Support Files */,
);
name = SideMenu;
path = ..;
sourceTree = "<group>";
};
849F7B062320DF40005DEB6A /* Classes */ = {
isa = PBXGroup;
children = (
849F7B7B23210C79005DEB6A /* SideMenuAnimationController.swift */,
849F7B7923210C79005DEB6A /* SideMenuInteractionController.swift */,
849F7B7723210C79005DEB6A /* SideMenuManager.swift */,
849F7B7623210C79005DEB6A /* SideMenuNavigationController.swift */,
849F7B7E23210C79005DEB6A /* SideMenuPresentationController.swift */,
849F7B7823210C79005DEB6A /* SideMenuPresentationStyle.swift */,
849F7B7A23210C79005DEB6A /* SideMenuPushCoordinator.swift */,
849F7B7C23210C79005DEB6A /* SideMenuTransitionController.swift */,
849F7B7D23210C79005DEB6A /* UITableViewVibrantCell.swift */,
);
name = Classes;
sourceTree = "<group>";
};
849F7B072320DF54005DEB6A /* Supporting */ = {
isa = PBXGroup;
children = (
849F7B6C23210C6E005DEB6A /* Deprecations.swift */,
849F7B6D23210C6E005DEB6A /* Extensions.swift */,
849F7B6E23210C6E005DEB6A /* Initializable.swift */,
849F7B6F23210C6E005DEB6A /* Print.swift */,
849F7B7023210C6E005DEB6A /* Protected.swift */,
);
name = Supporting;
sourceTree = "<group>";
};
9BDBD95ED116334D1B2835202D8D3060 /* Pods-Example */ = {
@@ -122,7 +158,7 @@
D6D7C498FA339E02BD53ECB8916CEA8E /* Pods-Example-dummy.m */,
AFECBC24E09D0D25F822C27BD944AFD4 /* Pods-Example-frameworks.sh */,
31C1D37707DFAA5E6A164BCC07834264 /* Pods-Example-Info.plist */,
7825A90E082A1582EB16256B0E722B3F /* Pods-Example-umbrella.h */,
7825A90E082A1582EB16256B0E722B3F /* Pods-Example.h */,
B45138496B85A072654D1D0F8EBBEDE5 /* Pods-Example.debug.xcconfig */,
243410B9535472556EA4BB6DBC133A0D /* Pods-Example.release.xcconfig */,
);
@@ -130,48 +166,16 @@
path = "Target Support Files/Pods-Example";
sourceTree = "<group>";
};
B2A94553E0F1BCEBF406CC59D290924B /* SideMenu */ = {
B9E764EFCD0B407437AC1550B5A6FB28 /* Pod */ = {
isa = PBXGroup;
children = (
F1B25193EDCA447F119795F68F75BF05 /* Extensions.swift */,
00F847D27577EF5335081BFA43A0BFA3 /* Initializable.swift */,
B5F10B146FA49E99D07F0FA0E38ABE8F /* Models.swift */,
2CB39D726F07EA27650309A1A3213412 /* Print.swift */,
13846826E721392191757B9033D6F63F /* Protected.swift */,
AB64592703EA9A196B5C0F07BA1A918A /* SideMenuInteractionController.swift */,
1FE7B8C8447DD35D435B2AF4A23E221C /* SideMenuManager.swift */,
61AFB3209BCB97295281AC6437FB346B /* SideMenuPresentationController.swift */,
D154DB98A04C7BD96E4EFBBD3FE0008A /* SideMenuPresentationStyle.swift */,
30C3188EE68841BE36716860BE079AF8 /* SideMenuTransitionController.swift */,
8F8B09C72B577EFDB20A3EFF4F0C668A /* UISideMenuNavigationController.swift */,
3ACA278071ED85D04DA83677D6C60528 /* UITableViewVibrantCell.swift */,
71A499AE33E397EBD7FA1A9D5B8440BA /* Pod */,
B5D061624D54AFB703E72CCF860BDB15 /* Support Files */,
849F7B062320DF40005DEB6A /* Classes */,
849F7B072320DF54005DEB6A /* Supporting */,
89DDCB61CB91FEE47235E0C0915F9F88 /* LICENSE */,
F2868E435B4FF74B943FC555CA3271AA /* README.md */,
BE3D03F947820C757C6A1858FE0784C9 /* SideMenu.podspec */,
);
name = SideMenu;
path = ..;
sourceTree = "<group>";
};
B5D061624D54AFB703E72CCF860BDB15 /* Support Files */ = {
isa = PBXGroup;
children = (
E656C89A7C466C66F803FC806E30B29E /* SideMenu.modulemap */,
BB1EC6DFBB713FC2F280D596714173EC /* SideMenu.xcconfig */,
9CF977D7FB42D367F2810037EBA59B7D /* SideMenu-dummy.m */,
1D01FD908F7943A6131CA6F66DD0CA68 /* SideMenu-Info.plist */,
BD4CEC04022777F53C1CA2113A43FACE /* SideMenu-prefix.pch */,
36C5772477B00653D86343BABD123EF3 /* SideMenu-umbrella.h */,
);
name = "Support Files";
path = "Pods/Target Support Files/SideMenu";
sourceTree = "<group>";
};
C0834CEBB1379A84116EF29F93051C60 /* iOS */ = {
isa = PBXGroup;
children = (
3212113385A8FBBDB272BD23C409FF61 /* Foundation.framework */,
);
name = iOS;
name = Pod;
sourceTree = "<group>";
};
CE2E825F08D3AD0FD76E6D78D7512ED0 /* Targets Support Files */ = {
@@ -186,27 +190,24 @@
isa = PBXGroup;
children = (
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */,
E72796DEAFDB67EE8F2BEAFC93FCD96A /* Development Pods */,
D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */,
0D8598CC67DCD15FA8FD2571BFA1FDD0 /* Development Pods */,
0161DC4DC33723D9E6F365301D5BEA4B /* Products */,
CE2E825F08D3AD0FD76E6D78D7512ED0 /* Targets Support Files */,
);
sourceTree = "<group>";
};
D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = {
F2C813E2A0676FE71DB8D655549E2635 /* Support Files */ = {
isa = PBXGroup;
children = (
C0834CEBB1379A84116EF29F93051C60 /* iOS */,
9A5090CE306074592C68F6FB7ADF43FA /* SideMenu.modulemap */,
5F375DA230E88A457A5F6021E054F56D /* SideMenu.xcconfig */,
4DF9702572C0E4370367755578F2ECE7 /* SideMenu-dummy.m */,
5B30AFEB50A77ED133026BBB542D4DC2 /* SideMenu-Info.plist */,
863A19DF8C4FEFD1D2DFF3C6C85F3013 /* SideMenu-prefix.pch */,
849F7B562320F3A4005DEB6A /* SideMenu.h */,
);
name = Frameworks;
sourceTree = "<group>";
};
E72796DEAFDB67EE8F2BEAFC93FCD96A /* Development Pods */ = {
isa = PBXGroup;
children = (
B2A94553E0F1BCEBF406CC59D290924B /* SideMenu */,
);
name = "Development Pods";
name = "Support Files";
path = "Pods/Target Support Files/SideMenu";
sourceTree = "<group>";
};
/* End PBXGroup section */
@@ -216,15 +217,16 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
D7BD58D0FF7BF7E887B6D70D4651D70B /* Pods-Example-umbrella.h in Headers */,
D7BD58D0FF7BF7E887B6D70D4651D70B /* Pods-Example.h in Headers */,
849F7B5B2320FCC6005DEB6A /* SideMenu.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E1521144D8813A046F85E2C67424FCEC /* Headers */ = {
EF1C6F3F91891316D1CEDAF556483650 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
DA6F42990A37DF6179D6386008BB87F8 /* SideMenu-umbrella.h in Headers */,
849F7B5E2320FD67005DEB6A /* SideMenu.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -252,12 +254,12 @@
};
C4A0A7D8591B67FB75E2E8D215E3735B /* SideMenu */ = {
isa = PBXNativeTarget;
buildConfigurationList = 935F4F1CC68EF5CF6D65BEC30B4BF4DD /* Build configuration list for PBXNativeTarget "SideMenu" */;
buildConfigurationList = CBE9024CB4C6BC4472FB1D55493FB8E9 /* Build configuration list for PBXNativeTarget "SideMenu" */;
buildPhases = (
E1521144D8813A046F85E2C67424FCEC /* Headers */,
0F01CC2B72C51E08DB4D032E8D7612D3 /* Sources */,
B55A7DF9A704D60A5DE58A98398D7779 /* Frameworks */,
4F04DC9108B63EA99399A1A2B583B21F /* Resources */,
EF1C6F3F91891316D1CEDAF556483650 /* Headers */,
C433EA7C535EE6A47E1A454086B654C2 /* Sources */,
D530FD6E7F0D492D9036605CB47EAB59 /* Frameworks */,
98655D66022D8A23B945B5400D0D96E7 /* Resources */,
);
buildRules = (
);
@@ -276,6 +278,14 @@
attributes = {
LastSwiftUpdateCheck = 1100;
LastUpgradeCheck = 1100;
TargetAttributes = {
0AEE99A309977BD12A049FF48AF9BA4B = {
LastSwiftMigration = 1030;
};
C4A0A7D8591B67FB75E2E8D215E3735B = {
LastSwiftMigration = 1030;
};
};
};
buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */;
compatibilityVersion = "Xcode 3.2";
@@ -296,7 +306,7 @@
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
4F04DC9108B63EA99399A1A2B583B21F /* Resources */ = {
98655D66022D8A23B945B5400D0D96E7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -313,23 +323,11 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
0F01CC2B72C51E08DB4D032E8D7612D3 /* Sources */ = {
C433EA7C535EE6A47E1A454086B654C2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
31E79D7BA42208D00E73C18CBAF1598E /* Extensions.swift in Sources */,
BD5C0C12B6BB0BF6DA294E095B35E38D /* Initializable.swift in Sources */,
0D2D410A6087D4E0A54642165913EF30 /* Models.swift in Sources */,
6E6E17C0E8351D23CB4B20332C70BE61 /* Print.swift in Sources */,
384CBA8850C8BF3A7AAB3A3D78844B1E /* Protected.swift in Sources */,
F1967413D21BCA08963F09969D47E152 /* SideMenu-dummy.m in Sources */,
A2ACFE2D997BC8F1DA4EE3064A4270DD /* SideMenuInteractionController.swift in Sources */,
287FA1360FD3EF72D700C54856C685C1 /* SideMenuManager.swift in Sources */,
614FC39555CB129D97FC24B2D953A427 /* SideMenuPresentationController.swift in Sources */,
D0B45D0F0E7B359807CAFB744FB80CE4 /* SideMenuPresentationStyle.swift in Sources */,
FCBFE25630B6309DF3213AE0F6F34D1A /* SideMenuTransitionController.swift in Sources */,
032FEB01E4C88E7C87032FCF9780FC7C /* UISideMenuNavigationController.swift in Sources */,
45A647715262A70BB9F2F4E7C1439C58 /* UITableViewVibrantCell.swift in Sources */,
E6F2CD13BC297BF5E7707DEDE9C7F271 /* SideMenu-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -337,7 +335,21 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
849F7B7523210C6E005DEB6A /* Protected.swift in Sources */,
849F7B8523210C79005DEB6A /* SideMenuTransitionController.swift in Sources */,
849F7B8623210C79005DEB6A /* UITableViewVibrantCell.swift in Sources */,
849F7B7123210C6E005DEB6A /* Deprecations.swift in Sources */,
849F7B8123210C79005DEB6A /* SideMenuPresentationStyle.swift in Sources */,
849F7B8323210C79005DEB6A /* SideMenuPushCoordinator.swift in Sources */,
849F7B7223210C6E005DEB6A /* Extensions.swift in Sources */,
849F7B8223210C79005DEB6A /* SideMenuInteractionController.swift in Sources */,
849F7B8723210C79005DEB6A /* SideMenuPresentationController.swift in Sources */,
849F7B8423210C79005DEB6A /* SideMenuAnimationController.swift in Sources */,
849F7B7423210C6E005DEB6A /* Print.swift in Sources */,
89B2CFA98A07964FBD2D7775FF5FB98D /* Pods-Example-dummy.m in Sources */,
849F7B8023210C79005DEB6A /* SideMenuManager.swift in Sources */,
849F7B7F23210C79005DEB6A /* SideMenuNavigationController.swift in Sources */,
849F7B7323210C6E005DEB6A /* Initializable.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -353,38 +365,6 @@
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
03F2FCB145390B05104D185513A47C8B /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BB1EC6DFBB713FC2F280D596714173EC /* SideMenu.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/SideMenu/SideMenu-prefix.pch";
INFOPLIST_FILE = "Target Support Files/SideMenu/SideMenu-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/SideMenu/SideMenu.modulemap";
PRODUCT_MODULE_NAME = SideMenu;
PRODUCT_NAME = SideMenu;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 5;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
196DFA3E4A09A28224918543529A1885 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -449,11 +429,46 @@
};
name = Debug;
};
56A1664171D7685EBD62329421925629 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5F375DA230E88A457A5F6021E054F56D /* SideMenu.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/SideMenu/SideMenu-prefix.pch";
INFOPLIST_FILE = "Target Support Files/SideMenu/SideMenu-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/SideMenu/SideMenu.modulemap";
PRODUCT_MODULE_NAME = SideMenu;
PRODUCT_NAME = SideMenu;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
70D2F3623D3AA27E6FB62D0291A05518 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 243410B9535472556EA4BB6DBC133A0D /* Pods-Example.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
@@ -477,6 +492,41 @@
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
801960B1745A4330B44246D5CDA31330 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5F375DA230E88A457A5F6021E054F56D /* SideMenu.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/SideMenu/SideMenu-prefix.pch";
INFOPLIST_FILE = "Target Support Files/SideMenu/SideMenu-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/SideMenu/SideMenu.modulemap";
PRODUCT_MODULE_NAME = SideMenu;
PRODUCT_NAME = SideMenu;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@@ -537,8 +587,7 @@
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
SYMROOT = "${SRCROOT}/../build";
};
@@ -549,6 +598,7 @@
baseConfigurationReference = B45138496B85A072654D1D0F8EBBEDE5 /* Pods-Example.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
@@ -572,45 +622,14 @@
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
FBB85502D70521CFA4D8AC919973525E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BB1EC6DFBB713FC2F280D596714173EC /* SideMenu.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = NO;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/SideMenu/SideMenu-prefix.pch";
INFOPLIST_FILE = "Target Support Files/SideMenu/SideMenu-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/SideMenu/SideMenu.modulemap";
PRODUCT_MODULE_NAME = SideMenu;
PRODUCT_NAME = SideMenu;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 5;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -632,11 +651,11 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
935F4F1CC68EF5CF6D65BEC30B4BF4DD /* Build configuration list for PBXNativeTarget "SideMenu" */ = {
CBE9024CB4C6BC4472FB1D55493FB8E9 /* Build configuration list for PBXNativeTarget "SideMenu" */ = {
isa = XCConfigurationList;
buildConfigurations = (
03F2FCB145390B05104D185513A47C8B /* Debug */,
FBB85502D70521CFA4D8AC919973525E /* Release */,
56A1664171D7685EBD62329421925629 /* Debug */,
801960B1745A4330B44246D5CDA31330 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@@ -1,16 +0,0 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_ExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_ExampleVersionString[];
@@ -1,5 +1,5 @@
framework module Pods_Example {
umbrella header "Pods-Example-umbrella.h"
umbrella header "Pods-Example.h"
export *
module * { export * }
-16
View File
@@ -1,16 +0,0 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double SideMenuVersionNumber;
FOUNDATION_EXPORT const unsigned char SideMenuVersionString[];
+1 -1
View File
@@ -1,5 +1,5 @@
framework module SideMenu {
umbrella header "SideMenu-umbrella.h"
umbrella header "SideMenu.h"
export *
module * { export * }
+60 -44
View File
@@ -1,11 +1,12 @@
# ▤ SideMenu
[![CircleCI](https://circleci.com/gh/jonkykong/SideMenu.svg?style=svg)](https://circleci.com/gh/jonkykong/SideMenu)
[![Version](https://img.shields.io/cocoapods/v/SideMenu.svg?style=flat-square)](http://cocoapods.org/pods/SideMenu)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat-square)](https://github.com/Carthage/Carthage)
[![License](https://img.shields.io/cocoapods/l/SideMenu.svg?style=flat-square)](http://cocoapods.org/pods/SideMenu)
[![Platform](https://img.shields.io/cocoapods/p/SideMenu.svg?style=flat-square)](http://cocoapods.org/pods/SideMenu)
### If you like SideMenu, give it a ★ at the top right of this page.
#### Using SideMenu in your app? [Send](mailto:yo@massappeal.co?subject=SideMenu%20in%20action!) me a link to your app in the app store!
#### SideMenu needs your help! If you're a skilled iOS developer and want to help maintain this repository and answer issues asked by the community, please [send me an email](mailto:yo@massappeal.co?subject=I%20Want%20To%20Help!).
> Hi, I'm Jon Kent and I am an iOS designer, developer, and mobile strategist. I love coffee and play the drums.
> * [**Hire me**](mailto:yo@massappeal.co?subject=Let's%20build%20something%20amazing) to help you make cool stuff. *Note: If you're having a problem with SideMenu, please open an [issue](https://github.com/jonkykong/SideMenu/issues/new) and do not email me.*
@@ -18,13 +19,14 @@
* **[Installation](#installation)**
* [CocoaPods](#cocoapods)
* [Carthage](#carthage)
* [Swift Package Manager](#swift-package-manager)
* **[Usage](#usage)**
* [Code-less Storyboard Implementation](#code-less-storyboard-implementation)
* [Code Implementation](#code-implementation)
* **[Customization](#customization)**
* [SideMenuManager](#sidemenumanager)
* [UISideMenuNavigationController](#uisidemenunavigationcontroller)
* [UISideMenuNavigationControllerDelegate](#uisidemenunavigationcontrollerdelegate)
* [SideMenuNavigationController](#sidemenunavigationcontroller)
* [SideMenuNavigationControllerDelegate](#sidemenunavigationcontrollerdelegate)
* [Advanced](#advanced)
* [Known Issues](#known-issues)
* [Thank You](#thank-you)
@@ -34,7 +36,7 @@
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] Four standard animation styles to choose from (there's even a parallax effect if you want to get weird).
- [x] Eight standard animation styles to choose from (there's even a parallax effect if you want to get weird).
- [x] Highly customizable without needing to write tons of custom code.
- [x] Supports continuous swiping between side menus on boths sides in a single gesture.
- [x] Global menu configuration. Set-up once and be done for all screens.
@@ -72,10 +74,10 @@ use_frameworks!
pod 'SideMenu'
# For Swift 5 use:
# pod 'SideMenu', '~> 5.0.0'
# pod 'SideMenu', '~> 6.0'
# For Swift 4 (no longer maintained) use:
# pod 'SideMenu', '~> 4.0.0'
# For Swift 4.2 (no longer maintained) use:
# pod 'SideMenu', '~> 5.0'
```
Then, run the following command:
@@ -101,12 +103,24 @@ To integrate SideMenu into your Xcode project using Carthage, specify it in your
github "jonkykong/SideMenu" "master"
```
### Swift Package Manager
The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. It is in early development, but SideMenu does support its use on supported platforms.
Once you have your Swift package set up, adding SideMenu as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.
```swift
dependencies: [
.package(url: "https://github.com/jonkykong/SideMenu.git", from: "6.0.0")
]
```
## Usage
### Code-less Storyboard Implementation
1. Create a Navigation Controller for a side menu. Set the `Custom Class` of the Navigation Controller to be `UISideMenuNavigationController` in the **Identity Inspector**. Set the `Module` to `SideMenu` (ignore this step if you've manually added SideMenu to your project). Create a Root View Controller for the Navigation Controller (shown as a UITableViewController below). Set up any Triggered Segues you want in that view controller.
1. Create a Navigation Controller for a side menu. Set the `Custom Class` of the Navigation Controller to be `SideMenuNavigationController` in the **Identity Inspector**. Set the `Module` to `SideMenu` (ignore this step if you've manually added SideMenu to your project). Create a Root View Controller for the Navigation Controller (shown as a UITableViewController below). Set up any Triggered Segues you want in that view controller.
![](https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Screenshot1.png)
2. Set the `Left Side` property of the `UISideMenuNavigationController` to On if you want it to appear from the left side of the screen, or Off/Default if you want it to appear from the right side.
2. Set the `Left Side` property of the `SideMenuNavigationController` to On if you want it to appear from the left side of the screen, or Off/Default if you want it to appear from the right side.
![](https://raw.githubusercontent.com/jonkykong/SideMenu/master/etc/Screenshot2.png)
3. Add a UIButton or UIBarButton to a view controller that you want to display the menu from. Set that button's Triggered Segues action to modally present the Navigation Controller from step 1.
@@ -122,10 +136,10 @@ import SideMenu
From a button, do something like this:
``` swift
// Define the menu
let menu = UISideMenuNavigationController(rootViewController: YourViewController)
// UISideMenuNavigationController is a subclass of UINavigationController, so do any additional configuration
let menu = SideMenuNavigationController(rootViewController: YourViewController)
// SideMenuNavigationController is a subclass of UINavigationController, so do any additional configuration
// of it here like setting its viewControllers. If you're using storyboards, you'll want to do something like:
// let menu = storyboard!.instantiateViewController(withIdentifier: "RightMenu") as! UISideMenuNavigationController
// let menu = storyboard!.instantiateViewController(withIdentifier: "RightMenu") as! SideMenuNavigationController
present(menu, animated: true, completion: nil)
```
@@ -137,11 +151,11 @@ dismiss(animated: true, completion: nil)
To use gestures you have to use the `SideMenuManager`. In your `AppDelegate` do something like this:
``` swift
// Define the menus
let menuLeftNavigationController = UISideMenuNavigationController(rootViewController: YourViewController)
SideMenuManager.default.menuLeftNavigationController = menuLeftNavigationController
let leftMenuNavigationController = SideMenuNavigationController(rootViewController: YourViewController)
SideMenuManager.default.leftMenuNavigationController = leftMenuNavigationController
let menuRightNavigationController = UISideMenuNavigationController(rootViewController: YourViewController)
SideMenuManager.default.menuRightNavigationController = menuRightNavigationController
let rightMenuNavigationController = SideMenuNavigationController(rootViewController: YourViewController)
SideMenuManager.default.rightMenuNavigationController = rightMenuNavigationController
// Setup 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!
@@ -149,9 +163,9 @@ SideMenuManager.default.addPanGestureToPresent(toView: self.navigationController
SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.navigationController!.view)
// (Optional) Prevent status bar area from turning black when menu appears:
menuLeftNavigationController.statusBarEndAlpha = 0
leftMenuNavigationController.statusBarEndAlpha = 0
// Copy all settings to the other menu
menuRightNavigationController.settings = menuLeftNavigationController.settings
rightMenuNavigationController.settings = leftMenuNavigationController.settings
```
That's it.
### Customization
@@ -159,9 +173,9 @@ That's it.
`SideMenuManager` supports the following:
``` swift
/// The left menu.
open var menuLeftNavigationController: UISideMenuNavigationController?
open var leftMenuNavigationController: SideMenuNavigationController?
/// The right menu.
public var menuRightNavigationController: UISideMenuNavigationController?
public var rightMenuNavigationController: SideMenuNavigationController?
/**
Adds screen edge gestures for both left and right sides to a view to present a menu.
@@ -188,8 +202,8 @@ public var menuRightNavigationController: UISideMenuNavigationController?
*/
@discardableResult public func addPanGestureToPresent(toView view: UIView) -> UIPanGestureRecognizer
```
#### UISideMenuNavigationController
`UISideMenuNavigationController` supports the following:
#### SideMenuNavigationController
`SideMenuNavigationController` supports the following:
``` swift
/// Prevents the same view controller (or a view controller of the same class) from being pushed more than once. Defaults to true.
var allowPushOfSameClassTwice: Bool = true
@@ -217,8 +231,10 @@ var dismissOnPush: Bool = true
var dismissOnRotation: Bool = true
/// Automatically dismisses the menu when app goes to the background.
var dismissWhenBackgrounded: Bool = true
/// Enable or disable gestures that would swipe to dismiss the menu. Default is true.
var enableSwipeGestures: Bool = true
/// Enable or disable a swipe gesture that dismisses the menu. Will not be triggered when `presentingViewControllerUserInteractionEnabled` is set to true. Default is true.
var enableSwipeToDismissGesture: Bool = true
/// Enable or disable a tap gesture that dismisses the menu. Will not be triggered when `presentingViewControllerUserInteractionEnabled` is set to true. Default is true.
var enableTapToDismissGesture: Bool = true
/// The animation initial spring velocity when a menu is displayed. Ignored when displayed with a gesture.
var initialSpringVelocity: CGFloat = 1
/// Whether the menu appears on the right or left side of the screen. Right is the default. This property cannot be changed after the menu has loaded.
@@ -256,45 +272,45 @@ var isHidden: Bool
There are 8 pre-defined `SideMenuPresentStyle` options:
``` swift
/// Menu slides in over the existing view.
static let menuSlideIn = SideMenuPresentStyle
static let menuSlideIn: SideMenuPresentStyle
/// The existing view slides out to reveal the menu underneath.
static let viewSlideOut = SideMenuPresentStyle
static let viewSlideOut: SideMenuPresentStyle
/// The existing view slides out while the menu slides in.
static let viewSlideOutMenuIn = SideMenuPresentStyle
static let viewSlideOutMenuIn: SideMenuPresentStyle
/// The menu dissolves in over the existing view.
static let menuDissolveIn = SideMenuPresentStyle
static let menuDissolveIn: SideMenuPresentStyle
/// The existing view slides out while the menu partially slides in.
static let viewSlideOutMenuPartialIn = SideMenuPresentStyle
static let viewSlideOutMenuPartialIn: SideMenuPresentStyle
/// The existing view slides out while the menu slides out from under it.
static let viewSlideOutMenuOut = SideMenuPresentStyle
static let viewSlideOutMenuOut: SideMenuPresentStyle
/// The existing view slides out while the menu partially slides out from under it.
static let viewSlideOutMenuPartialOut = SideMenuPresentStyle
static let viewSlideOutMenuPartialOut: SideMenuPresentStyle
/// The existing view slides out and shrinks to reveal the menu underneath.
static let viewSlideOutMenuZoom = SideMenuPresentStyle
static let viewSlideOutMenuZoom: SideMenuPresentStyle
```
#### UISideMenuNavigationControllerDelegate
To receive notifications when a menu is displayed from a view controller, have it adhere to the `UISideMenuNavigationControllerDelegate` protocol:
#### SideMenuNavigationControllerDelegate
To receive notifications when a menu is displayed from a view controller, have it adhere to the `SideMenuNavigationControllerDelegate` protocol:
``` swift
extension MyViewController: UISideMenuNavigationControllerDelegate {
extension MyViewController: SideMenuNavigationControllerDelegate {
func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Appearing! (animated: \(animated))")
}
func sideMenuDidAppear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuDidAppear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Appeared! (animated: \(animated))")
}
func sideMenuWillDisappear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuWillDisappear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Disappearing! (animated: \(animated))")
}
func sideMenuDidDisappear(menu: UISideMenuNavigationController, animated: Bool) {
func sideMenuDidDisappear(menu: SideMenuNavigationController, animated: Bool) {
print("SideMenu Disappeared! (animated: \(animated))")
}
}
```
*Note: setting the `sideMenuDelegate` property on `UISideMenuNavigationController` is optional. If your view controller adheres to the protocol then the methods will be called automatically.*
*Note: setting the `sideMenuDelegate` property on `SideMenuNavigationController` is optional. If your view controller adheres to the protocol then the methods will be called automatically.*
### Advanced
<details>
<summary>Click for Details</summary>
@@ -306,9 +322,9 @@ For simplicity, `SideMenuManager.default` serves as the primary instance as most
let customSideMenuManager = SideMenuManager()
```
2. Setup and display menus with your custom instance the same as you would with the `SideMenuManager.default` instance.
3. If using Storyboards, subclass your instance of `UISideMenuNavigationController` and set its `sideMenuManager` property to your custom instance. This must be done before `viewDidLoad` is called:
3. If using Storyboards, subclass your instance of `SideMenuNavigationController` and set its `sideMenuManager` property to your custom instance. This must be done before `viewDidLoad` is called:
``` swift
class MySideMenuNavigationController: UISideMenuNavigationController {
class MySideMenuNavigationController: SideMenuNavigationController {
let customSideMenuManager = SideMenuManager()
@@ -319,10 +335,10 @@ class MySideMenuNavigationController: UISideMenuNavigationController {
}
}
```
Alternatively, you can set `sideMenuManager` from the view controller that segues to your UISideMenuNavigationController:
Alternatively, you can set `sideMenuManager` from the view controller that segues to your SideMenuNavigationController:
``` swift
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let sideMenuNavigationController = segue.destination as? UISideMenuNavigationController {
if let sideMenuNavigationController = segue.destination as? SideMenuNavigationController {
sideMenuNavigationController.sideMenuManager = customSideMenuManager
}
}
+2 -2
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = "SideMenu"
s.version = "6.0.0"
s.version = "6.4.1"
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.
@@ -29,7 +29,7 @@ Pod::Spec.new do |s|
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '10.0'
s.swift_version = '5'
s.swift_version = '5.0'
s.source_files = 'Pod/Classes/**/*'
# s.resource_bundles = {
+200 -46
View File
@@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
65FF1B3E1DE321D8007B0845 /* SideMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 65FF1B3D1DE321D8007B0845 /* SideMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
7B48A0D61DCB2487002990A1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B48A0D51DCB2487002990A1 /* AppDelegate.swift */; };
7B48A0DD1DCB2487002990A1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7B48A0DC1DCB2487002990A1 /* Assets.xcassets */; };
7B48A0F61DCB2518002990A1 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B48A0F31DCB2518002990A1 /* MainViewController.swift */; };
@@ -15,36 +14,68 @@
7B48A0F81DCB2518002990A1 /* SideMenuTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B48A0F51DCB2518002990A1 /* SideMenuTableViewController.swift */; };
7B552D5D1DCC65830010301C /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B552D5C1DCC65830010301C /* Launch Screen.storyboard */; };
7B5FA9B61DCB269700278DF6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B5FA9B51DCB269700278DF6 /* Main.storyboard */; };
84276D8A2282929A0095B7C5 /* SideMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84276D892282929A0095B7C5 /* SideMenuManager.swift */; };
8461A2D51E145A08001DA4F8 /* UISideMenuNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8461A2D11E145A08001DA4F8 /* UISideMenuNavigationController.swift */; };
8461A2D61E145A08001DA4F8 /* UITableViewVibrantCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8461A2D21E145A08001DA4F8 /* UITableViewVibrantCell.swift */; };
8432CC0422FFBCF5003D2BBD /* ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8432CC0322FFBCF5003D2BBD /* ExampleTests.swift */; };
849F7B9623210C9A005DEB6A /* UITableViewVibrantCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8823210C9A005DEB6A /* UITableViewVibrantCell.swift */; };
849F7B9723210C9A005DEB6A /* SideMenuTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8923210C9A005DEB6A /* SideMenuTransitionController.swift */; };
849F7B9823210C9A005DEB6A /* SideMenuAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8A23210C9A005DEB6A /* SideMenuAnimationController.swift */; };
849F7B9923210C9A005DEB6A /* SideMenuInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8B23210C9A005DEB6A /* SideMenuInteractionController.swift */; };
849F7B9A23210C9A005DEB6A /* Initializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8C23210C9A005DEB6A /* Initializable.swift */; };
849F7B9B23210C9A005DEB6A /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8D23210C9A005DEB6A /* Extensions.swift */; };
849F7B9C23210C9A005DEB6A /* SideMenuPresentationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8E23210C9A005DEB6A /* SideMenuPresentationStyle.swift */; };
849F7B9D23210C9A005DEB6A /* SideMenuNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B8F23210C9A005DEB6A /* SideMenuNavigationController.swift */; };
849F7B9E23210C9A005DEB6A /* SideMenuPushCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B9023210C9A005DEB6A /* SideMenuPushCoordinator.swift */; };
849F7B9F23210C9A005DEB6A /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B9123210C9A005DEB6A /* Deprecations.swift */; };
849F7BA023210C9A005DEB6A /* Print.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B9223210C9A005DEB6A /* Print.swift */; };
849F7BA123210C9A005DEB6A /* SideMenuPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B9323210C9A005DEB6A /* SideMenuPresentationController.swift */; };
849F7BA223210C9A005DEB6A /* SideMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B9423210C9A005DEB6A /* SideMenuManager.swift */; };
849F7BA323210C9A005DEB6A /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849F7B9523210C9A005DEB6A /* Protected.swift */; };
849F7BA423225F7F005DEB6A /* SideMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 849F7B67232104BD005DEB6A /* SideMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
84B489B51DD469B000D6CB43 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 84B489B21DD469B000D6CB43 /* LICENSE */; };
84B489B71DD469B000D6CB43 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 84B489B41DD469B000D6CB43 /* README.md */; };
84B489BA1DD469DA00D6CB43 /* SideMenu.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 84B489B91DD469DA00D6CB43 /* SideMenu.podspec */; };
ACD6DAED90DE36FEA68CDF38 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47896ABC5C8830D88945A8D3 /* Pods_Example.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
8432CC0622FFBCF5003D2BBD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7B9DC8FB1DC6E8C1000D4007 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 7B48A0D21DCB2487002990A1;
remoteInfo = Example;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
1F17B9D56ADA958C611FAA83 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
281FB58A39C022692CEEBF0D /* Pods-Example-ExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-ExampleTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-ExampleTests/Pods-Example-ExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
47896ABC5C8830D88945A8D3 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
52C8DD7BE43A8987854CA726 /* Pods_Example_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
65FF1B3D1DE321D8007B0845 /* SideMenu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SideMenu.h; path = SideMenu/SideMenu.h; sourceTree = "<group>"; };
7B48A0D31DCB2487002990A1 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
7B48A0D51DCB2487002990A1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7B48A0DC1DCB2487002990A1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7B48A0E11DCB2487002990A1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7B48A0EA1DCB2487002990A1 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
7B48A0EC1DCB2487002990A1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7B48A0F31DCB2518002990A1 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
7B48A0F41DCB2518002990A1 /* PresentedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentedViewController.swift; sourceTree = "<group>"; };
7B48A0F51DCB2518002990A1 /* SideMenuTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SideMenuTableViewController.swift; sourceTree = "<group>"; };
7B552D5C1DCC65830010301C /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
7B5FA9B51DCB269700278DF6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
7B9DC9041DC6E8C1000D4007 /* SideMenu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SideMenu.framework; sourceTree = BUILT_PRODUCTS_DIR; };
84276D892282929A0095B7C5 /* SideMenuManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuManager.swift; path = Pod/Classes/SideMenuManager.swift; sourceTree = "<group>"; };
8461A2D11E145A08001DA4F8 /* UISideMenuNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UISideMenuNavigationController.swift; path = Pod/Classes/UISideMenuNavigationController.swift; sourceTree = "<group>"; };
8461A2D21E145A08001DA4F8 /* UITableViewVibrantCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UITableViewVibrantCell.swift; path = Pod/Classes/UITableViewVibrantCell.swift; sourceTree = "<group>"; };
8432CC0122FFBCF4003D2BBD /* ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
8432CC0322FFBCF5003D2BBD /* ExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleTests.swift; sourceTree = "<group>"; };
8432CC0522FFBCF5003D2BBD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
849F7B67232104BD005DEB6A /* SideMenu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SideMenu.h; path = SideMenu/SideMenu.h; sourceTree = "<group>"; };
849F7B8823210C9A005DEB6A /* UITableViewVibrantCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UITableViewVibrantCell.swift; path = Pod/Classes/UITableViewVibrantCell.swift; sourceTree = "<group>"; };
849F7B8923210C9A005DEB6A /* SideMenuTransitionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuTransitionController.swift; path = Pod/Classes/SideMenuTransitionController.swift; sourceTree = "<group>"; };
849F7B8A23210C9A005DEB6A /* SideMenuAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuAnimationController.swift; path = Pod/Classes/SideMenuAnimationController.swift; sourceTree = "<group>"; };
849F7B8B23210C9A005DEB6A /* SideMenuInteractionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuInteractionController.swift; path = Pod/Classes/SideMenuInteractionController.swift; sourceTree = "<group>"; };
849F7B8C23210C9A005DEB6A /* Initializable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Initializable.swift; path = Pod/Classes/Initializable.swift; sourceTree = "<group>"; };
849F7B8D23210C9A005DEB6A /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = Pod/Classes/Extensions.swift; sourceTree = "<group>"; };
849F7B8E23210C9A005DEB6A /* SideMenuPresentationStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuPresentationStyle.swift; path = Pod/Classes/SideMenuPresentationStyle.swift; sourceTree = "<group>"; };
849F7B8F23210C9A005DEB6A /* SideMenuNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuNavigationController.swift; path = Pod/Classes/SideMenuNavigationController.swift; sourceTree = "<group>"; };
849F7B9023210C9A005DEB6A /* SideMenuPushCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuPushCoordinator.swift; path = Pod/Classes/SideMenuPushCoordinator.swift; sourceTree = "<group>"; };
849F7B9123210C9A005DEB6A /* Deprecations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Deprecations.swift; path = Pod/Classes/Deprecations.swift; sourceTree = "<group>"; };
849F7B9223210C9A005DEB6A /* Print.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Print.swift; path = Pod/Classes/Print.swift; sourceTree = "<group>"; };
849F7B9323210C9A005DEB6A /* SideMenuPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuPresentationController.swift; path = Pod/Classes/SideMenuPresentationController.swift; sourceTree = "<group>"; };
849F7B9423210C9A005DEB6A /* SideMenuManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SideMenuManager.swift; path = Pod/Classes/SideMenuManager.swift; sourceTree = "<group>"; };
849F7B9523210C9A005DEB6A /* Protected.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Pod/Classes/Protected.swift; sourceTree = "<group>"; };
84B489B21DD469B000D6CB43 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
84B489B41DD469B000D6CB43 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
84B489B91DD469DA00D6CB43 /* SideMenu.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SideMenu.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
@@ -52,7 +83,6 @@
C7DA85E73FE6228663AD9236 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
C9E09E1C686BF24AD4976EA7 /* Pods-ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ExampleTests/Pods-ExampleTests.release.xcconfig"; sourceTree = "<group>"; };
CAE41BBB5F14E59C1FA0A821 /* Pods-Example-ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-ExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example-ExampleTests/Pods-Example-ExampleTests.release.xcconfig"; sourceTree = "<group>"; };
D1435FAD2F735E43F383BE96 /* Pods_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -60,7 +90,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
ACD6DAED90DE36FEA68CDF38 /* Pods_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -71,6 +100,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
8432CBFE22FFBCF4003D2BBD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -86,10 +122,21 @@
65FF1B3F1DE33097007B0845 /* Source */ = {
isa = PBXGroup;
children = (
84276D892282929A0095B7C5 /* SideMenuManager.swift */,
8461A2D11E145A08001DA4F8 /* UISideMenuNavigationController.swift */,
8461A2D21E145A08001DA4F8 /* UITableViewVibrantCell.swift */,
65FF1B3D1DE321D8007B0845 /* SideMenu.h */,
849F7B67232104BD005DEB6A /* SideMenu.h */,
849F7B9123210C9A005DEB6A /* Deprecations.swift */,
849F7B8D23210C9A005DEB6A /* Extensions.swift */,
849F7B8C23210C9A005DEB6A /* Initializable.swift */,
849F7B9223210C9A005DEB6A /* Print.swift */,
849F7B9523210C9A005DEB6A /* Protected.swift */,
849F7B8A23210C9A005DEB6A /* SideMenuAnimationController.swift */,
849F7B8B23210C9A005DEB6A /* SideMenuInteractionController.swift */,
849F7B9423210C9A005DEB6A /* SideMenuManager.swift */,
849F7B8F23210C9A005DEB6A /* SideMenuNavigationController.swift */,
849F7B9323210C9A005DEB6A /* SideMenuPresentationController.swift */,
849F7B8E23210C9A005DEB6A /* SideMenuPresentationStyle.swift */,
849F7B9023210C9A005DEB6A /* SideMenuPushCoordinator.swift */,
849F7B8923210C9A005DEB6A /* SideMenuTransitionController.swift */,
849F7B8823210C9A005DEB6A /* UITableViewVibrantCell.swift */,
);
name = Source;
sourceTree = "<group>";
@@ -108,25 +155,15 @@
path = Example;
sourceTree = "<group>";
};
7B48A0E91DCB2487002990A1 /* ExampleTests */ = {
isa = PBXGroup;
children = (
7B48A0EA1DCB2487002990A1 /* Tests.swift */,
7B48A0EC1DCB2487002990A1 /* Info.plist */,
);
path = ExampleTests;
sourceTree = "<group>";
};
7B9DC8FA1DC6E8C1000D4007 = {
isa = PBXGroup;
children = (
65FF1B3F1DE33097007B0845 /* Source */,
84B489B81DD469B900D6CB43 /* Podspec Metadata */,
7B48A0D41DCB2487002990A1 /* Example */,
7B48A0E91DCB2487002990A1 /* ExampleTests */,
8432CC0222FFBCF5003D2BBD /* ExampleTests */,
7B9DC9051DC6E8C1000D4007 /* Products */,
9FB98148377EAEC00E35AC14 /* Pods */,
9C94EEEBD250FF394115AAFC /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -135,10 +172,20 @@
children = (
7B9DC9041DC6E8C1000D4007 /* SideMenu.framework */,
7B48A0D31DCB2487002990A1 /* Example.app */,
8432CC0122FFBCF4003D2BBD /* ExampleTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
8432CC0222FFBCF5003D2BBD /* ExampleTests */ = {
isa = PBXGroup;
children = (
8432CC0322FFBCF5003D2BBD /* ExampleTests.swift */,
8432CC0522FFBCF5003D2BBD /* Info.plist */,
);
path = ExampleTests;
sourceTree = "<group>";
};
84B489B81DD469B900D6CB43 /* Podspec Metadata */ = {
isa = PBXGroup;
children = (
@@ -149,16 +196,6 @@
name = "Podspec Metadata";
sourceTree = "<group>";
};
9C94EEEBD250FF394115AAFC /* Frameworks */ = {
isa = PBXGroup;
children = (
47896ABC5C8830D88945A8D3 /* Pods_Example.framework */,
D1435FAD2F735E43F383BE96 /* Pods_ExampleTests.framework */,
52C8DD7BE43A8987854CA726 /* Pods_Example_ExampleTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9FB98148377EAEC00E35AC14 /* Pods */ = {
isa = PBXGroup;
children = (
@@ -179,7 +216,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
65FF1B3E1DE321D8007B0845 /* SideMenu.h in Headers */,
849F7BA423225F7F005DEB6A /* SideMenu.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -223,13 +260,31 @@
productReference = 7B9DC9041DC6E8C1000D4007 /* SideMenu.framework */;
productType = "com.apple.product-type.framework";
};
8432CC0022FFBCF4003D2BBD /* ExampleTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8432CC0822FFBCF5003D2BBD /* Build configuration list for PBXNativeTarget "ExampleTests" */;
buildPhases = (
8432CBFD22FFBCF4003D2BBD /* Sources */,
8432CBFE22FFBCF4003D2BBD /* Frameworks */,
8432CBFF22FFBCF4003D2BBD /* Resources */,
);
buildRules = (
);
dependencies = (
8432CC0722FFBCF5003D2BBD /* PBXTargetDependency */,
);
name = ExampleTests;
productName = ExampleTests;
productReference = 8432CC0122FFBCF4003D2BBD /* ExampleTests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7B9DC8FB1DC6E8C1000D4007 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastSwiftUpdateCheck = 1030;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = jonkykong;
TargetAttributes = {
@@ -241,9 +296,15 @@
};
7B9DC9031DC6E8C1000D4007 = {
CreatedOnToolsVersion = 8.0;
LastSwiftMigration = 0900;
LastSwiftMigration = 1030;
ProvisioningStyle = Automatic;
};
8432CC0022FFBCF4003D2BBD = {
CreatedOnToolsVersion = 10.3;
DevelopmentTeam = QTJ767UH3L;
ProvisioningStyle = Automatic;
TestTargetID = 7B48A0D21DCB2487002990A1;
};
};
};
buildConfigurationList = 7B9DC8FE1DC6E8C1000D4007 /* Build configuration list for PBXProject "SideMenu" */;
@@ -262,6 +323,7 @@
targets = (
7B9DC9031DC6E8C1000D4007 /* SideMenu */,
7B48A0D21DCB2487002990A1 /* Example */,
8432CC0022FFBCF4003D2BBD /* ExampleTests */,
);
};
/* End PBXProject section */
@@ -287,6 +349,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
8432CBFF22FFBCF4003D2BBD /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -344,14 +413,41 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8461A2D51E145A08001DA4F8 /* UISideMenuNavigationController.swift in Sources */,
84276D8A2282929A0095B7C5 /* SideMenuManager.swift in Sources */,
8461A2D61E145A08001DA4F8 /* UITableViewVibrantCell.swift in Sources */,
849F7B9923210C9A005DEB6A /* SideMenuInteractionController.swift in Sources */,
849F7B9B23210C9A005DEB6A /* Extensions.swift in Sources */,
849F7BA323210C9A005DEB6A /* Protected.swift in Sources */,
849F7B9F23210C9A005DEB6A /* Deprecations.swift in Sources */,
849F7B9A23210C9A005DEB6A /* Initializable.swift in Sources */,
849F7BA223210C9A005DEB6A /* SideMenuManager.swift in Sources */,
849F7B9E23210C9A005DEB6A /* SideMenuPushCoordinator.swift in Sources */,
849F7BA123210C9A005DEB6A /* SideMenuPresentationController.swift in Sources */,
849F7B9C23210C9A005DEB6A /* SideMenuPresentationStyle.swift in Sources */,
849F7B9823210C9A005DEB6A /* SideMenuAnimationController.swift in Sources */,
849F7BA023210C9A005DEB6A /* Print.swift in Sources */,
849F7B9723210C9A005DEB6A /* SideMenuTransitionController.swift in Sources */,
849F7B9623210C9A005DEB6A /* UITableViewVibrantCell.swift in Sources */,
849F7B9D23210C9A005DEB6A /* SideMenuNavigationController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8432CBFD22FFBCF4003D2BBD /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8432CC0422FFBCF5003D2BBD /* ExampleTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
8432CC0722FFBCF5003D2BBD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7B48A0D21DCB2487002990A1 /* Example */;
targetProxy = 8432CC0622FFBCF5003D2BBD /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
7B48A0ED1DCB2487002990A1 /* Debug */ = {
isa = XCBuildConfiguration;
@@ -415,6 +511,7 @@
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -478,6 +575,7 @@
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -541,6 +639,53 @@
};
name = Release;
};
8432CC0922FFBCF5003D2BBD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = QTJ767UH3L;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = ExampleTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = co.massappeal.ExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = Example;
};
name = Debug;
};
8432CC0A22FFBCF5003D2BBD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = QTJ767UH3L;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = ExampleTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = co.massappeal.ExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = Example;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -571,6 +716,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8432CC0822FFBCF5003D2BBD /* Build configuration list for PBXNativeTarget "ExampleTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8432CC0922FFBCF5003D2BBD /* Debug */,
8432CC0A22FFBCF5003D2BBD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 7B9DC8FB1DC6E8C1000D4007 /* Project object */;
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B48A0D21DCB2487002990A1"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:SideMenu.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8432CC0022FFBCF4003D2BBD"
BuildableName = "ExampleTests.xctest"
BlueprintName = "ExampleTests"
ReferencedContainer = "container:SideMenu.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B48A0D21DCB2487002990A1"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:SideMenu.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B48A0D21DCB2487002990A1"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:SideMenu.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7B48A0D21DCB2487002990A1"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:SideMenu.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 135 KiB