Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b62749bff | |||
| 7179713c18 | |||
| 60f6f204c1 | |||
| 98c5b2b3e3 | |||
| e8882a952d | |||
| efc2e11fb2 | |||
| 36662fa0f3 | |||
| dce89eb448 | |||
| 32f1101e86 | |||
| d25de76a92 | |||
| 59faed8ef9 | |||
| 4f990e86a8 |
@@ -0,0 +1,16 @@
|
||||
// swift-tools-version:4.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")
|
||||
]
|
||||
)
|
||||
|
||||
@@ -12,15 +12,15 @@ extension NSObject: InitializableClass {}
|
||||
internal extension UIView {
|
||||
|
||||
@discardableResult func untransformed(_ block: () -> CGFloat) -> CGFloat {
|
||||
let transform = self.transform
|
||||
self.transform = .identity
|
||||
let t = self.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) {
|
||||
@@ -31,10 +31,10 @@ internal extension UIView {
|
||||
}
|
||||
|
||||
static func animationsEnabled(_ block: () -> Void) {
|
||||
let areAnimationsEnabled = UIView.areAnimationsEnabled
|
||||
UIView.setAnimationsEnabled(true)
|
||||
let a = areAnimationsEnabled
|
||||
setAnimationsEnabled(true)
|
||||
block()
|
||||
UIView.setAnimationsEnabled(areAnimationsEnabled)
|
||||
setAnimationsEnabled(a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +308,7 @@ open class SideMenuNavigationController: UINavigationController {
|
||||
}
|
||||
}
|
||||
|
||||
SideMenuPushCoordinator(config:
|
||||
let pushed = SideMenuPushCoordinator(config:
|
||||
.init(
|
||||
allowPushOfSameClassTwice: allowPushOfSameClassTwice,
|
||||
alongsideTransition: alongsideTransition,
|
||||
@@ -318,6 +318,10 @@ open class SideMenuNavigationController: UINavigationController {
|
||||
toViewController: viewController
|
||||
)
|
||||
).start()
|
||||
|
||||
if !pushed {
|
||||
super.pushViewController(viewController, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
override open var transitioningDelegate: UIViewControllerTransitioningDelegate? {
|
||||
@@ -603,7 +607,7 @@ private extension SideMenuNavigationController {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
|
||||
[UIApplication.willChangeStatusBarFrameNotification,
|
||||
UIApplication.didEnterBackgroundNotification].forEach {
|
||||
UIApplication.didEnterBackgroundNotification].forEach {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: $0, object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol Coordinator {
|
||||
associatedtype Model: CoordinatorModel
|
||||
|
||||
init(config: Model)
|
||||
func start()
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -37,15 +37,19 @@ internal final class SideMenuPushCoordinator: Coordinator {
|
||||
self.config = config
|
||||
}
|
||||
|
||||
func start() {
|
||||
guard let fromNavigationController = config.fromViewController as? UINavigationController else { return }
|
||||
@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 var navigationController = potentialNavigationController as? UINavigationController else {
|
||||
return Print.warning(.cannotPush, arguments: String(describing: potentialNavigationController.self), required: true)
|
||||
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
|
||||
@@ -58,7 +62,7 @@ internal final class SideMenuPushCoordinator: Coordinator {
|
||||
|
||||
if let lastViewController = navigationController.viewControllers.last,
|
||||
!config.allowPushOfSameClassTwice && type(of: lastViewController) == type(of: toViewController) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
toViewController.navigationItem.hidesBackButton = config.pushStyle.hidesBackButton
|
||||
@@ -66,32 +70,38 @@ internal final class SideMenuPushCoordinator: Coordinator {
|
||||
switch config.pushStyle {
|
||||
|
||||
case .default:
|
||||
break
|
||||
navigationController.pushViewController(toViewController, animated: config.animated)
|
||||
return true
|
||||
|
||||
// subMenu handled earlier
|
||||
case .subMenu:
|
||||
navigationController = fromNavigationController
|
||||
break
|
||||
return false
|
||||
|
||||
case .popWhenPossible:
|
||||
for subViewController in navigationController.viewControllers.reversed() {
|
||||
if type(of: subViewController) == type(of: toViewController) {
|
||||
navigationController.popToViewController(subViewController, animated: config.animated)
|
||||
return
|
||||
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 { break }
|
||||
guard let preservedViewController = filtered.last else {
|
||||
navigationController.pushViewController(toViewController, animated: config.animated)
|
||||
return true
|
||||
}
|
||||
viewControllers = viewControllers.filter { subViewController in subViewController !== preservedViewController }
|
||||
viewControllers.append(preservedViewController)
|
||||
return navigationController.setViewControllers(viewControllers, animated: config.animated)
|
||||
navigationController.setViewControllers(viewControllers, animated: config.animated)
|
||||
return true
|
||||
|
||||
case .replace:
|
||||
return navigationController.setViewControllers([toViewController], animated: config.animated)
|
||||
navigationController.setViewControllers([toViewController], animated: config.animated)
|
||||
return true
|
||||
}
|
||||
|
||||
navigationController.pushViewController(toViewController, animated: config.animated)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* **[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)
|
||||
@@ -102,6 +103,18 @@ 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 `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.
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SideMenu"
|
||||
s.version = "6.2.7"
|
||||
s.version = "6.3.0"
|
||||
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.
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
7B552D5D1DCC65830010301C /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B552D5C1DCC65830010301C /* Launch Screen.storyboard */; };
|
||||
7B5FA9B61DCB269700278DF6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B5FA9B51DCB269700278DF6 /* Main.storyboard */; };
|
||||
8432CC0422FFBCF5003D2BBD /* ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8432CC0322FFBCF5003D2BBD /* ExampleTests.swift */; };
|
||||
849F7B68232104BD005DEB6A /* SideMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 849F7B67232104BD005DEB6A /* SideMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
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 */; };
|
||||
@@ -30,6 +29,7 @@
|
||||
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 */; };
|
||||
@@ -61,7 +61,7 @@
|
||||
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 = "Pods/Target Support Files/SideMenu/SideMenu.h"; 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>"; };
|
||||
@@ -216,7 +216,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
849F7B68232104BD005DEB6A /* SideMenu.h in Headers */,
|
||||
849F7BA423225F7F005DEB6A /* SideMenu.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user