Compare commits

..

7 Commits

Author SHA1 Message Date
Ivan Vorobei 8348cd6396 Update to 1.7.2
Fix bugs with events delegate.
2019-07-11 01:17:48 +03:00
Ivan Vorobei 9f4c1be56d Update to 1.7.1
Add confirmation to dismiss by scroll. Change `SPStorkControllerConfirmDelegate` to required methods. Update example.
2019-07-10 21:46:53 +03:00
Ivan Vorobei de779aebef Update example 2019-07-10 17:44:59 +03:00
Ivan Vorobei 1785822242 Update to 1.7
Add confirmation fitures.
2019-07-10 17:43:37 +03:00
Ivan Vorobei 1514ea5481 Update README.md 2019-07-06 16:38:20 +03:00
Ivan Vorobei ec81b9f5dd Update README.md 2019-07-06 16:37:47 +03:00
Ivan Vorobei 7381066b36 Update to 1.6.9 2019-07-05 23:33:54 +03:00
16 changed files with 409 additions and 174 deletions
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
F437B75122D62D7700E6074C /* SPStorkControllerConfirmDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75022D62D7700E6074C /* SPStorkControllerConfirmDelegate.swift */; };
F445CA8721AED92600184254 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F445CA8621AED92600184254 /* AppDelegate.swift */; };
F445CA8921AED92600184254 /* Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = F445CA8821AED92600184254 /* Controller.swift */; };
F445CA8E21AED92700184254 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F445CA8D21AED92700184254 /* Assets.xcassets */; };
@@ -151,6 +152,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F437B75022D62D7700E6074C /* SPStorkControllerConfirmDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPStorkControllerConfirmDelegate.swift; sourceTree = "<group>"; };
F445CA8321AED92600184254 /* stork-controller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "stork-controller.app"; sourceTree = BUILT_PRODUCTS_DIR; };
F445CA8621AED92600184254 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F445CA8821AED92600184254 /* Controller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Controller.swift; sourceTree = "<group>"; };
@@ -876,6 +878,7 @@
isa = PBXGroup;
children = (
F4E0E38F22CF6B940020D754 /* SPStorkControllerDelegate.swift */,
F437B75022D62D7700E6074C /* SPStorkControllerConfirmDelegate.swift */,
);
path = Protocols;
sourceTree = "<group>";
@@ -1086,6 +1089,7 @@
F4DB84DB22609C05005082AA /* SPUserDefaultsExtenshion.swift in Sources */,
F4DB849A22609C05005082AA /* SPFormLabelTableViewCell.swift in Sources */,
F4DB84AD22609C05005082AA /* SPCircleCloseButton.swift in Sources */,
F437B75122D62D7700E6074C /* SPStorkControllerConfirmDelegate.swift in Sources */,
F4DB84AE22609C05005082AA /* SPAppStoreActionButton.swift in Sources */,
F4E0E39C22CF6B940020D754 /* SPStorkControllerDelegate.swift in Sources */,
F4DB84BB22609C05005082AA /* SPBlurView.swift in Sources */,
+15
View File
@@ -28,6 +28,8 @@ class Controller: UIViewController {
@objc func presentModalViewController() {
let modal = ModalViewController()
let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.storkDelegate = self
transitionDelegate.confirmDelegate = modal
modal.transitioningDelegate = transitionDelegate
modal.modalPresentationStyle = .custom
self.present(modal, animated: true, completion: nil)
@@ -36,8 +38,21 @@ class Controller: UIViewController {
@objc func presentModalTableViewController() {
let modal = ModalTableViewController()
let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.storkDelegate = self
transitionDelegate.confirmDelegate = modal
modal.transitioningDelegate = transitionDelegate
modal.modalPresentationStyle = .custom
self.present(modal, animated: true, completion: nil)
}
}
extension Controller: SPStorkControllerDelegate {
func didDismissStorkByTap() {
print("SPStorkControllerDelegate - didDismissStorkByTap")
}
func didDismissStorkBySwipe() {
print("SPStorkControllerDelegate - didDismissStorkBySwipe")
}
}
@@ -0,0 +1,29 @@
// The MIT License (MIT)
// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import UIKit
@objc public protocol SPStorkControllerConfirmDelegate: class {
var needConfirm: Bool { get }
func confirm(_ completion: @escaping (_ isConfirmed: Bool)->())
}
@@ -29,12 +29,13 @@ public enum SPStorkController {
let translation = -(scrollView.contentOffset.y + scrollView.contentInset.top)
if translation >= 0 {
if controller.isBeingPresented { return }
scrollView.transform = CGAffineTransform(translationX: 0, y: -translation)
scrollView.scrollIndicatorInsets.top = (indicatorInset ?? 0) + translation
scrollView.subviews.forEach {
$0.transform = CGAffineTransform(translationX: 0, y: -translation)
}
presentationController.setIndicator(style: scrollView.isTracking ? .line : .arrow)
if translation >= presentationController.translateForDismiss * 0.4 {
if !scrollView.isTracking && !scrollView.isDragging {
presentationController.presentedViewController.dismiss(animated: true, completion: {
presentationController.dismissWithConfirmation(prepare: nil, completion: {
presentationController.storkDelegate?.didDismissStorkBySwipe?()
})
return
@@ -35,6 +35,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
var transitioningDelegate: SPStorkTransitioningDelegate?
weak var storkDelegate: SPStorkControllerDelegate?
weak var confirmDelegate: SPStorkControllerConfirmDelegate?
var pan: UIPanGestureRecognizer?
var tap: UITapGestureRecognizer?
@@ -50,6 +51,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
private var snapshotViewWidthConstraint: NSLayoutConstraint?
private var snapshotViewAspectRatioConstraint: NSLayoutConstraint?
var workConfirmation: Bool = false
private var workGester: Bool = false
private var startDismissing: Bool = false
private var afterReleaseDismissing: Bool = false
@@ -68,7 +70,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
return factor
}
private var feedbackGenerator: UIImpactFeedbackGenerator = UIImpactFeedbackGenerator(style: .light)
private var feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
override var presentedView: UIView? {
let view = self.presentedViewController.view
@@ -105,7 +107,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
if self.showIndicator {
self.indicatorView.color = self.indicatorColor
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction))
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.tapIndicator))
tap.cancelsTouchesInView = false
self.indicatorView.addGestureRecognizer(tap)
presentedView.addSubview(self.indicatorView)
@@ -120,7 +122,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
self.gradeView.alpha = 0
if self.showCloseButton {
self.closeButton.addTarget(self, action: #selector(self.dismissAction), for: .touchUpInside)
self.closeButton.addTarget(self, action: #selector(self.tapCloseButton), for: .touchUpInside)
presentedView.addSubview(self.closeButton)
}
self.updateLayoutCloseButton()
@@ -207,7 +209,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
self.updateSnapshotAspectRatio()
if self.tapAroundToDismissEnabled {
self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction))
self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.tapArround))
self.tap?.cancelsTouchesInView = false
self.snapshotViewContainer.addGestureRecognizer(self.tap!)
}
@@ -221,21 +223,13 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
}
}
@objc func dismissAction() {
self.presentingViewController.view.endEditing(true)
self.presentedViewController.view.endEditing(true)
self.presentedViewController.dismiss(animated: true, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
override func dismissalTransitionWillBegin() {
super.dismissalTransitionWillBegin()
guard let containerView = containerView else { return }
self.startDismissing = true
let initialFrame: CGRect = presentingViewController.isPresentedAsStork ? presentingViewController.view.frame : containerView.bounds
let initialTransform = CGAffineTransform.identity
.translatedBy(x: 0, y: -initialFrame.origin.y)
.translatedBy(x: 0, y: self.topSpace)
@@ -312,6 +306,56 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
extension SPStorkPresentationController {
@objc func tapIndicator() {
self.dismissWithConfirmation(prepare: nil, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
@objc func tapArround() {
self.dismissWithConfirmation(prepare: nil, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
@objc func tapCloseButton() {
self.dismissWithConfirmation(prepare: nil, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
public func dismissWithConfirmation(prepare: (()->())?, completion: (()->())?) {
let dismiss = {
self.presentingViewController.view.endEditing(true)
self.presentedViewController.view.endEditing(true)
self.presentedViewController.dismiss(animated: true, completion: {
completion?()
})
}
guard let confirmDelegate = self.confirmDelegate else {
dismiss()
return
}
if self.workConfirmation { return }
if confirmDelegate.needConfirm {
prepare?()
self.workConfirmation = true
confirmDelegate.confirm({ (isConfirmed) in
self.workConfirmation = false
self.afterReleaseDismissing = false
if isConfirmed {
dismiss()
}
})
} else {
dismiss()
}
}
@objc func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
guard gestureRecognizer.isEqual(self.pan), self.swipeToDismissEnabled else { return }
@@ -334,11 +378,8 @@ extension SPStorkPresentationController {
case .ended:
self.workGester = false
let translation = gestureRecognizer.translation(in: presentedView).y
if translation >= self.translateForDismiss {
self.presentedViewController.dismiss(animated: true, completion: {
self.storkDelegate?.didDismissStorkBySwipe?()
})
} else {
let toDefault = {
self.indicatorView.style = .arrow
UIView.animate(
withDuration: 0.6,
@@ -352,6 +393,14 @@ extension SPStorkPresentationController {
self.gradeView.alpha = self.alpha
})
}
if translation >= self.translateForDismiss {
self.dismissWithConfirmation(prepare: toDefault, completion: {
self.storkDelegate?.didDismissStorkBySwipe?()
})
} else {
toDefault()
}
default:
break
}
@@ -401,7 +450,7 @@ extension SPStorkPresentationController {
let elasticThreshold: CGFloat = 120
let translationFactor: CGFloat = 1 / 2
if translation >= 0 {
let translationForModal: CGFloat = {
if translation >= elasticThreshold {
@@ -427,8 +476,10 @@ extension SPStorkPresentationController {
let afterRealseDismissing = (translation >= self.translateForDismiss)
if afterRealseDismissing != self.afterReleaseDismissing {
self.afterReleaseDismissing = afterRealseDismissing
if self.hapticMoments.contains(.willDismissIfRelease) {
self.feedbackGenerator.impactOccurred()
if !self.workConfirmation {
if self.hapticMoments.contains(.willDismissIfRelease) {
self.feedbackGenerator.impactOccurred()
}
}
}
}
@@ -460,8 +511,6 @@ extension SPStorkPresentationController {
private func updateLayoutIndicator() {
self.indicatorView.style = .line
self.indicatorView.sizeToFit()
//self.indicatorView.frame.origin.y = 12
//self.indicatorView.center.x = presentedView.frame.width / 2
}
private func updateLayoutCloseButton() {
@@ -34,6 +34,7 @@ public final class SPStorkTransitioningDelegate: NSObject, UIViewControllerTrans
public var cornerRadius: CGFloat = 10
public var hapticMoments: [SPStorkHapticMoments] = [.willDismissIfRelease]
public weak var storkDelegate: SPStorkControllerDelegate? = nil
public weak var confirmDelegate: SPStorkControllerConfirmDelegate? = nil
public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
let controller = SPStorkPresentationController(presentedViewController: presented, presenting: presenting)
@@ -49,6 +50,7 @@ public final class SPStorkTransitioningDelegate: NSObject, UIViewControllerTrans
controller.hapticMoments = self.hapticMoments
controller.transitioningDelegate = self
controller.storkDelegate = self.storkDelegate
controller.confirmDelegate = self.confirmDelegate
return controller
}
@@ -49,7 +49,11 @@ class ModalTableViewController: UIViewController {
}
@objc func dismissAction() {
self.dismiss()
if let storkPresentationController = self.presentationController as? SPStorkPresentationController {
storkPresentationController.dismissWithConfirmation(prepare: nil, completion: {
print("Custom completion for confirmation. Confirmation is optional.")
})
}
}
}
@@ -74,8 +78,25 @@ extension ModalTableViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.tableView {
SPStorkController.scrollViewDidScroll(scrollView, indicatorInset: self.navBar.height)
SPStorkController.scrollViewDidScroll(scrollView)
}
}
}
extension ModalTableViewController: SPStorkControllerConfirmDelegate {
var needConfirm: Bool {
return true
}
func confirm(_ completion: @escaping (Bool) -> ()) {
let alertController = UIAlertController(title: "Need dismiss?", message: "It test confirm option for SPStorkController", preferredStyle: .actionSheet)
alertController.addDestructiveAction(title: "Confirm", complection: {
completion(true)
})
alertController.addCancelAction(title: "Cancel") {
completion(false)
}
self.present(alertController)
}
}
@@ -20,7 +20,11 @@ class ModalViewController: UIViewController {
}
@objc func dismissAction() {
self.dismiss()
if let storkPresentationController = self.presentationController as? SPStorkPresentationController {
storkPresentationController.dismissWithConfirmation(prepare: nil, completion: {
print("Custom completion for confirmation. Confirmation is optional.")
})
}
}
override func viewWillAppear(_ animated: Bool) {
@@ -32,3 +36,20 @@ class ModalViewController: UIViewController {
}
}
extension ModalViewController: SPStorkControllerConfirmDelegate {
var needConfirm: Bool {
return true
}
func confirm(_ completion: @escaping (Bool) -> ()) {
let alertController = UIAlertController(title: "Need dismiss?", message: "It test confirm option for SPStorkController", preferredStyle: .actionSheet)
alertController.addDestructiveAction(title: "Confirm", complection: {
completion(true)
})
alertController.addCancelAction(title: "Cancel") {
completion(false)
}
self.present(alertController)
}
}
+18 -10
View File
@@ -9,11 +9,9 @@ You can download example [Debts - Spending tracker](https://itunes.apple.com/app
[![xcode-shop.com](https://github.com/ivanvorobei/SPPermission/blob/master/Resources/Buttons/Xcode%20Shop%20Button%20-%203.svg)](https://xcode-shop.com)
If you like the project, do not forget to `put star ★` or follow me in twitter:
If you like the project, do not forget to `put star ★` and follow me on GitHub:
[![https://twitter.com/varabeis](https://github.com/ivanvorobei/SPPermission/blob/master/Resources/Buttons/Twitter-2.svg)](https://twitter.com/varabeis)
See project's backers in [Sponsors](https://github.com/ivanvorobei/SPStorkController#sponsors) section.
[![https://github.com/ivanvorobei](https://github.com/ivanvorobei/SPPermission/blob/master/Resources/Buttons/Follow%20me%20-%2016.svg)](https://github.com/ivanvorobei)
## Navigate
@@ -32,6 +30,7 @@ See project's backers in [Sponsors](https://github.com/ivanvorobei/SPStorkContro
- [Add Navigation Bar](#add-navigation-bar)
- [Working with UIScrollView](#working-with-uiscrollview)
- [UITableView & UICollectionView](#working-with-uitableview--uicollectionview)
- [Confirm](#confirm)
- [Delegate](#delegate)
- [Storyboard](#storyboard)
- [Sheets in iOS 13](#sheets-in-ios-13)
@@ -263,12 +262,6 @@ func scrollViewDidScroll(_ scrollView: UIScrollView) {
}
```
If you use vertical indicator for your scroll view, for best result pass your top inset to function. Parametr optional:
```swift
SPStorkController.scrollViewDidScroll(scrollView, indicatorInset: 25)
```
### Working with UITableView & UICollectionView
Working with a collections classes is not difficult. In the `Example` folder you can find an implementation. However, I will give a couple of tips for making the table look better.
@@ -282,6 +275,21 @@ tableView.scrollIndicatorInsets.top = self.navBar.height
Please, also use `SPStorkController.scrollViewDidScroll` function in scroll delegate for more interactiveness with your collection or table view.
### Confirm
For confirm closing by swipe, use `SPStorkControllerConfirmDelegate`. Implenet protocol:
```swift
@objc public protocol SPStorkControllerConfirmDelegate: class {
var needConfirm: Bool { get }
func confirm(_ completion: @escaping (_ isConfirmed: Bool)->())
}
```
and set `confirmDelegate` property to object, which protocol impleneted. Function `confirm` call if `needConfirm` set to `true` and controller try closing by swipe. Pass `isConfirmed` with result. Best options use `UIAlertController` with `.actionSheet` style for confirmation.
### Delegate
You can check events by implement `SPStorkControllerDelegate` and set delegate for `transitionDelegate`:
+1 -1
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SPStorkController"
s.version = "1.6.8"
s.version = "1.7.2"
s.summary = "Very similar to the controllers displayed in Apple Music, Podcasts and Mail Apple's applications."
s.homepage = "https://github.com/IvanVorobei/SPStorkController"
s.source = { :git => "https://github.com/IvanVorobei/SPStorkController.git", :tag => s.version }
+112 -108
View File
@@ -7,39 +7,41 @@
objects = {
/* Begin PBXBuildFile section */
F437B76722D62FF000E6074C /* SPStorkHaptic.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75422D62FF000E6074C /* SPStorkHaptic.swift */; };
F437B76822D62FF000E6074C /* SPStorkSeque.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75522D62FF000E6074C /* SPStorkSeque.swift */; };
F437B76922D62FF000E6074C /* SPStorkCodeDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75722D62FF000E6074C /* SPStorkCodeDraw.swift */; };
F437B76A22D62FF000E6074C /* SPStorkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75822D62FF000E6074C /* SPStorkController.swift */; };
F437B76B22D62FF000E6074C /* SPStorkTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75A22D62FF000E6074C /* SPStorkTransitioningDelegate.swift */; };
F437B76C22D62FF000E6074C /* SPStorkPresentingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75B22D62FF000E6074C /* SPStorkPresentingAnimationController.swift */; };
F437B76D22D62FF000E6074C /* SPStorkPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75C22D62FF000E6074C /* SPStorkPresentationController.swift */; };
F437B76E22D62FF000E6074C /* SPStorkDismissingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75D22D62FF000E6074C /* SPStorkDismissingAnimationController.swift */; };
F437B76F22D62FF000E6074C /* SPStorkViewControllerExtenshion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B75F22D62FF000E6074C /* SPStorkViewControllerExtenshion.swift */; };
F437B77022D62FF000E6074C /* SPStorkCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B76122D62FF000E6074C /* SPStorkCloseButton.swift */; };
F437B77122D62FF000E6074C /* SPStorkIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B76222D62FF000E6074C /* SPStorkIndicatorView.swift */; };
F437B77222D62FF000E6074C /* SPStorkCloseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B76322D62FF000E6074C /* SPStorkCloseView.swift */; };
F437B77322D62FF000E6074C /* SPStorkControllerConfirmDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B76522D62FF000E6074C /* SPStorkControllerConfirmDelegate.swift */; };
F437B77422D62FF000E6074C /* SPStorkControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F437B76622D62FF000E6074C /* SPStorkControllerDelegate.swift */; };
F4DB85222260A4FD005082AA /* SPStorkController.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DB85202260A4FD005082AA /* SPStorkController.h */; settings = {ATTRIBUTES = (Public, ); }; };
F4EF61BC22B58B8600E76099 /* SPStorkHaptic.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61AA22B58B8500E76099 /* SPStorkHaptic.swift */; };
F4EF61BD22B58B8600E76099 /* SPStorkSeque.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61AB22B58B8500E76099 /* SPStorkSeque.swift */; };
F4EF61BE22B58B8600E76099 /* SPStorkCodeDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61AD22B58B8500E76099 /* SPStorkCodeDraw.swift */; };
F4EF61BF22B58B8600E76099 /* SPStorkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61AE22B58B8500E76099 /* SPStorkController.swift */; };
F4EF61C022B58B8600E76099 /* SPStorkTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B022B58B8500E76099 /* SPStorkTransitioningDelegate.swift */; };
F4EF61C122B58B8600E76099 /* SPStorkPresentingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B122B58B8500E76099 /* SPStorkPresentingAnimationController.swift */; };
F4EF61C222B58B8600E76099 /* SPStorkPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B222B58B8500E76099 /* SPStorkPresentationController.swift */; };
F4EF61C322B58B8600E76099 /* SPStorkDismissingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B322B58B8500E76099 /* SPStorkDismissingAnimationController.swift */; };
F4EF61C422B58B8600E76099 /* SPStorkViewControllerExtenshion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B522B58B8500E76099 /* SPStorkViewControllerExtenshion.swift */; };
F4EF61C522B58B8600E76099 /* SPStorkCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B722B58B8500E76099 /* SPStorkCloseButton.swift */; };
F4EF61C622B58B8600E76099 /* SPStorkIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B822B58B8500E76099 /* SPStorkIndicatorView.swift */; };
F4EF61C722B58B8600E76099 /* SPStorkCloseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61B922B58B8500E76099 /* SPStorkCloseView.swift */; };
F4EF61C822B58B8600E76099 /* SPStorkControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EF61BB22B58B8500E76099 /* SPStorkControllerDelegate.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F437B75422D62FF000E6074C /* SPStorkHaptic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkHaptic.swift; sourceTree = "<group>"; };
F437B75522D62FF000E6074C /* SPStorkSeque.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkSeque.swift; sourceTree = "<group>"; };
F437B75722D62FF000E6074C /* SPStorkCodeDraw.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkCodeDraw.swift; sourceTree = "<group>"; };
F437B75822D62FF000E6074C /* SPStorkController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkController.swift; sourceTree = "<group>"; };
F437B75A22D62FF000E6074C /* SPStorkTransitioningDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkTransitioningDelegate.swift; sourceTree = "<group>"; };
F437B75B22D62FF000E6074C /* SPStorkPresentingAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkPresentingAnimationController.swift; sourceTree = "<group>"; };
F437B75C22D62FF000E6074C /* SPStorkPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkPresentationController.swift; sourceTree = "<group>"; };
F437B75D22D62FF000E6074C /* SPStorkDismissingAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkDismissingAnimationController.swift; sourceTree = "<group>"; };
F437B75F22D62FF000E6074C /* SPStorkViewControllerExtenshion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkViewControllerExtenshion.swift; sourceTree = "<group>"; };
F437B76122D62FF000E6074C /* SPStorkCloseButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkCloseButton.swift; sourceTree = "<group>"; };
F437B76222D62FF000E6074C /* SPStorkIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkIndicatorView.swift; sourceTree = "<group>"; };
F437B76322D62FF000E6074C /* SPStorkCloseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkCloseView.swift; sourceTree = "<group>"; };
F437B76522D62FF000E6074C /* SPStorkControllerConfirmDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkControllerConfirmDelegate.swift; sourceTree = "<group>"; };
F437B76622D62FF000E6074C /* SPStorkControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkControllerDelegate.swift; sourceTree = "<group>"; };
F4DB851D2260A4FD005082AA /* SPStorkController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SPStorkController.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F4DB85202260A4FD005082AA /* SPStorkController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPStorkController.h; sourceTree = "<group>"; };
F4DB85212260A4FD005082AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F4EF61AA22B58B8500E76099 /* SPStorkHaptic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkHaptic.swift; sourceTree = "<group>"; };
F4EF61AB22B58B8500E76099 /* SPStorkSeque.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkSeque.swift; sourceTree = "<group>"; };
F4EF61AD22B58B8500E76099 /* SPStorkCodeDraw.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkCodeDraw.swift; sourceTree = "<group>"; };
F4EF61AE22B58B8500E76099 /* SPStorkController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkController.swift; sourceTree = "<group>"; };
F4EF61B022B58B8500E76099 /* SPStorkTransitioningDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkTransitioningDelegate.swift; sourceTree = "<group>"; };
F4EF61B122B58B8500E76099 /* SPStorkPresentingAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkPresentingAnimationController.swift; sourceTree = "<group>"; };
F4EF61B222B58B8500E76099 /* SPStorkPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkPresentationController.swift; sourceTree = "<group>"; };
F4EF61B322B58B8500E76099 /* SPStorkDismissingAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkDismissingAnimationController.swift; sourceTree = "<group>"; };
F4EF61B522B58B8500E76099 /* SPStorkViewControllerExtenshion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkViewControllerExtenshion.swift; sourceTree = "<group>"; };
F4EF61B722B58B8500E76099 /* SPStorkCloseButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkCloseButton.swift; sourceTree = "<group>"; };
F4EF61B822B58B8500E76099 /* SPStorkIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkIndicatorView.swift; sourceTree = "<group>"; };
F4EF61B922B58B8500E76099 /* SPStorkCloseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkCloseView.swift; sourceTree = "<group>"; };
F4EF61BB22B58B8500E76099 /* SPStorkControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPStorkControllerDelegate.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -53,6 +55,75 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F437B75222D62FF000E6074C /* SPStorkController */ = {
isa = PBXGroup;
children = (
F437B75322D62FF000E6074C /* Models */,
F437B75522D62FF000E6074C /* SPStorkSeque.swift */,
F437B75622D62FF000E6074C /* CodeDraw */,
F437B75822D62FF000E6074C /* SPStorkController.swift */,
F437B75922D62FF000E6074C /* TransitioningDelegate */,
F437B75E22D62FF000E6074C /* Extenshion */,
F437B76022D62FF000E6074C /* Views */,
F437B76422D62FF000E6074C /* Protocols */,
);
path = SPStorkController;
sourceTree = "<group>";
};
F437B75322D62FF000E6074C /* Models */ = {
isa = PBXGroup;
children = (
F437B75422D62FF000E6074C /* SPStorkHaptic.swift */,
);
path = Models;
sourceTree = "<group>";
};
F437B75622D62FF000E6074C /* CodeDraw */ = {
isa = PBXGroup;
children = (
F437B75722D62FF000E6074C /* SPStorkCodeDraw.swift */,
);
path = CodeDraw;
sourceTree = "<group>";
};
F437B75922D62FF000E6074C /* TransitioningDelegate */ = {
isa = PBXGroup;
children = (
F437B75A22D62FF000E6074C /* SPStorkTransitioningDelegate.swift */,
F437B75B22D62FF000E6074C /* SPStorkPresentingAnimationController.swift */,
F437B75C22D62FF000E6074C /* SPStorkPresentationController.swift */,
F437B75D22D62FF000E6074C /* SPStorkDismissingAnimationController.swift */,
);
path = TransitioningDelegate;
sourceTree = "<group>";
};
F437B75E22D62FF000E6074C /* Extenshion */ = {
isa = PBXGroup;
children = (
F437B75F22D62FF000E6074C /* SPStorkViewControllerExtenshion.swift */,
);
path = Extenshion;
sourceTree = "<group>";
};
F437B76022D62FF000E6074C /* Views */ = {
isa = PBXGroup;
children = (
F437B76122D62FF000E6074C /* SPStorkCloseButton.swift */,
F437B76222D62FF000E6074C /* SPStorkIndicatorView.swift */,
F437B76322D62FF000E6074C /* SPStorkCloseView.swift */,
);
path = Views;
sourceTree = "<group>";
};
F437B76422D62FF000E6074C /* Protocols */ = {
isa = PBXGroup;
children = (
F437B76522D62FF000E6074C /* SPStorkControllerConfirmDelegate.swift */,
F437B76622D62FF000E6074C /* SPStorkControllerDelegate.swift */,
);
path = Protocols;
sourceTree = "<group>";
};
F4437E4F22B50918006E6498 /* Supporting Files */ = {
isa = PBXGroup;
children = (
@@ -81,80 +152,12 @@
F4DB851F2260A4FD005082AA /* Source */ = {
isa = PBXGroup;
children = (
F4EF61A822B58B8500E76099 /* SPStorkController */,
F437B75222D62FF000E6074C /* SPStorkController */,
F4437E4F22B50918006E6498 /* Supporting Files */,
);
path = Source;
sourceTree = "<group>";
};
F4EF61A822B58B8500E76099 /* SPStorkController */ = {
isa = PBXGroup;
children = (
F4EF61A922B58B8500E76099 /* Models */,
F4EF61AB22B58B8500E76099 /* SPStorkSeque.swift */,
F4EF61AC22B58B8500E76099 /* CodeDraw */,
F4EF61AE22B58B8500E76099 /* SPStorkController.swift */,
F4EF61AF22B58B8500E76099 /* TransitioningDelegate */,
F4EF61B422B58B8500E76099 /* Extenshion */,
F4EF61B622B58B8500E76099 /* Views */,
F4EF61BA22B58B8500E76099 /* Protocols */,
);
path = SPStorkController;
sourceTree = "<group>";
};
F4EF61A922B58B8500E76099 /* Models */ = {
isa = PBXGroup;
children = (
F4EF61AA22B58B8500E76099 /* SPStorkHaptic.swift */,
);
path = Models;
sourceTree = "<group>";
};
F4EF61AC22B58B8500E76099 /* CodeDraw */ = {
isa = PBXGroup;
children = (
F4EF61AD22B58B8500E76099 /* SPStorkCodeDraw.swift */,
);
path = CodeDraw;
sourceTree = "<group>";
};
F4EF61AF22B58B8500E76099 /* TransitioningDelegate */ = {
isa = PBXGroup;
children = (
F4EF61B022B58B8500E76099 /* SPStorkTransitioningDelegate.swift */,
F4EF61B122B58B8500E76099 /* SPStorkPresentingAnimationController.swift */,
F4EF61B222B58B8500E76099 /* SPStorkPresentationController.swift */,
F4EF61B322B58B8500E76099 /* SPStorkDismissingAnimationController.swift */,
);
path = TransitioningDelegate;
sourceTree = "<group>";
};
F4EF61B422B58B8500E76099 /* Extenshion */ = {
isa = PBXGroup;
children = (
F4EF61B522B58B8500E76099 /* SPStorkViewControllerExtenshion.swift */,
);
path = Extenshion;
sourceTree = "<group>";
};
F4EF61B622B58B8500E76099 /* Views */ = {
isa = PBXGroup;
children = (
F4EF61B722B58B8500E76099 /* SPStorkCloseButton.swift */,
F4EF61B822B58B8500E76099 /* SPStorkIndicatorView.swift */,
F4EF61B922B58B8500E76099 /* SPStorkCloseView.swift */,
);
path = Views;
sourceTree = "<group>";
};
F4EF61BA22B58B8500E76099 /* Protocols */ = {
isa = PBXGroup;
children = (
F4EF61BB22B58B8500E76099 /* SPStorkControllerDelegate.swift */,
);
path = Protocols;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -233,19 +236,20 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4EF61BF22B58B8600E76099 /* SPStorkController.swift in Sources */,
F4EF61C322B58B8600E76099 /* SPStorkDismissingAnimationController.swift in Sources */,
F4EF61C222B58B8600E76099 /* SPStorkPresentationController.swift in Sources */,
F4EF61C422B58B8600E76099 /* SPStorkViewControllerExtenshion.swift in Sources */,
F4EF61BD22B58B8600E76099 /* SPStorkSeque.swift in Sources */,
F4EF61C522B58B8600E76099 /* SPStorkCloseButton.swift in Sources */,
F4EF61C822B58B8600E76099 /* SPStorkControllerDelegate.swift in Sources */,
F4EF61C122B58B8600E76099 /* SPStorkPresentingAnimationController.swift in Sources */,
F4EF61C622B58B8600E76099 /* SPStorkIndicatorView.swift in Sources */,
F4EF61C722B58B8600E76099 /* SPStorkCloseView.swift in Sources */,
F4EF61BE22B58B8600E76099 /* SPStorkCodeDraw.swift in Sources */,
F4EF61BC22B58B8600E76099 /* SPStorkHaptic.swift in Sources */,
F4EF61C022B58B8600E76099 /* SPStorkTransitioningDelegate.swift in Sources */,
F437B76A22D62FF000E6074C /* SPStorkController.swift in Sources */,
F437B76E22D62FF000E6074C /* SPStorkDismissingAnimationController.swift in Sources */,
F437B76D22D62FF000E6074C /* SPStorkPresentationController.swift in Sources */,
F437B76F22D62FF000E6074C /* SPStorkViewControllerExtenshion.swift in Sources */,
F437B76822D62FF000E6074C /* SPStorkSeque.swift in Sources */,
F437B77422D62FF000E6074C /* SPStorkControllerDelegate.swift in Sources */,
F437B77322D62FF000E6074C /* SPStorkControllerConfirmDelegate.swift in Sources */,
F437B77022D62FF000E6074C /* SPStorkCloseButton.swift in Sources */,
F437B76C22D62FF000E6074C /* SPStorkPresentingAnimationController.swift in Sources */,
F437B77122D62FF000E6074C /* SPStorkIndicatorView.swift in Sources */,
F437B77222D62FF000E6074C /* SPStorkCloseView.swift in Sources */,
F437B76922D62FF000E6074C /* SPStorkCodeDraw.swift in Sources */,
F437B76722D62FF000E6074C /* SPStorkHaptic.swift in Sources */,
F437B76B22D62FF000E6074C /* SPStorkTransitioningDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -0,0 +1,29 @@
// The MIT License (MIT)
// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import UIKit
@objc public protocol SPStorkControllerConfirmDelegate: class {
var needConfirm: Bool { get }
func confirm(_ completion: @escaping (_ isConfirmed: Bool)->())
}
@@ -29,12 +29,13 @@ public enum SPStorkController {
let translation = -(scrollView.contentOffset.y + scrollView.contentInset.top)
if translation >= 0 {
if controller.isBeingPresented { return }
scrollView.transform = CGAffineTransform(translationX: 0, y: -translation)
scrollView.scrollIndicatorInsets.top = (indicatorInset ?? 0) + translation
scrollView.subviews.forEach {
$0.transform = CGAffineTransform(translationX: 0, y: -translation)
}
presentationController.setIndicator(style: scrollView.isTracking ? .line : .arrow)
if translation >= presentationController.translateForDismiss * 0.4 {
if !scrollView.isTracking && !scrollView.isDragging {
presentationController.presentedViewController.dismiss(animated: true, completion: {
presentationController.dismissWithConfirmation(prepare: nil, completion: {
presentationController.storkDelegate?.didDismissStorkBySwipe?()
})
return
@@ -35,6 +35,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
var transitioningDelegate: SPStorkTransitioningDelegate?
weak var storkDelegate: SPStorkControllerDelegate?
weak var confirmDelegate: SPStorkControllerConfirmDelegate?
var pan: UIPanGestureRecognizer?
var tap: UITapGestureRecognizer?
@@ -50,6 +51,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
private var snapshotViewWidthConstraint: NSLayoutConstraint?
private var snapshotViewAspectRatioConstraint: NSLayoutConstraint?
var workConfirmation: Bool = false
private var workGester: Bool = false
private var startDismissing: Bool = false
private var afterReleaseDismissing: Bool = false
@@ -68,7 +70,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
return factor
}
private var feedbackGenerator: UIImpactFeedbackGenerator = UIImpactFeedbackGenerator(style: .light)
private var feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
override var presentedView: UIView? {
let view = self.presentedViewController.view
@@ -105,7 +107,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
if self.showIndicator {
self.indicatorView.color = self.indicatorColor
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction))
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.tapIndicator))
tap.cancelsTouchesInView = false
self.indicatorView.addGestureRecognizer(tap)
presentedView.addSubview(self.indicatorView)
@@ -120,7 +122,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
self.gradeView.alpha = 0
if self.showCloseButton {
self.closeButton.addTarget(self, action: #selector(self.dismissAction), for: .touchUpInside)
self.closeButton.addTarget(self, action: #selector(self.tapCloseButton), for: .touchUpInside)
presentedView.addSubview(self.closeButton)
}
self.updateLayoutCloseButton()
@@ -207,7 +209,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
self.updateSnapshotAspectRatio()
if self.tapAroundToDismissEnabled {
self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction))
self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.tapArround))
self.tap?.cancelsTouchesInView = false
self.snapshotViewContainer.addGestureRecognizer(self.tap!)
}
@@ -221,21 +223,13 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
}
}
@objc func dismissAction() {
self.presentingViewController.view.endEditing(true)
self.presentedViewController.view.endEditing(true)
self.presentedViewController.dismiss(animated: true, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
override func dismissalTransitionWillBegin() {
super.dismissalTransitionWillBegin()
guard let containerView = containerView else { return }
self.startDismissing = true
let initialFrame: CGRect = presentingViewController.isPresentedAsStork ? presentingViewController.view.frame : containerView.bounds
let initialTransform = CGAffineTransform.identity
.translatedBy(x: 0, y: -initialFrame.origin.y)
.translatedBy(x: 0, y: self.topSpace)
@@ -312,6 +306,56 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
extension SPStorkPresentationController {
@objc func tapIndicator() {
self.dismissWithConfirmation(prepare: nil, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
@objc func tapArround() {
self.dismissWithConfirmation(prepare: nil, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
@objc func tapCloseButton() {
self.dismissWithConfirmation(prepare: nil, completion: {
self.storkDelegate?.didDismissStorkByTap?()
})
}
public func dismissWithConfirmation(prepare: (()->())?, completion: (()->())?) {
let dismiss = {
self.presentingViewController.view.endEditing(true)
self.presentedViewController.view.endEditing(true)
self.presentedViewController.dismiss(animated: true, completion: {
completion?()
})
}
guard let confirmDelegate = self.confirmDelegate else {
dismiss()
return
}
if self.workConfirmation { return }
if confirmDelegate.needConfirm {
prepare?()
self.workConfirmation = true
confirmDelegate.confirm({ (isConfirmed) in
self.workConfirmation = false
self.afterReleaseDismissing = false
if isConfirmed {
dismiss()
}
})
} else {
dismiss()
}
}
@objc func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
guard gestureRecognizer.isEqual(self.pan), self.swipeToDismissEnabled else { return }
@@ -334,11 +378,8 @@ extension SPStorkPresentationController {
case .ended:
self.workGester = false
let translation = gestureRecognizer.translation(in: presentedView).y
if translation >= self.translateForDismiss {
self.presentedViewController.dismiss(animated: true, completion: {
self.storkDelegate?.didDismissStorkBySwipe?()
})
} else {
let toDefault = {
self.indicatorView.style = .arrow
UIView.animate(
withDuration: 0.6,
@@ -352,6 +393,14 @@ extension SPStorkPresentationController {
self.gradeView.alpha = self.alpha
})
}
if translation >= self.translateForDismiss {
self.dismissWithConfirmation(prepare: toDefault, completion: {
self.storkDelegate?.didDismissStorkBySwipe?()
})
} else {
toDefault()
}
default:
break
}
@@ -401,7 +450,7 @@ extension SPStorkPresentationController {
let elasticThreshold: CGFloat = 120
let translationFactor: CGFloat = 1 / 2
if translation >= 0 {
let translationForModal: CGFloat = {
if translation >= elasticThreshold {
@@ -427,8 +476,10 @@ extension SPStorkPresentationController {
let afterRealseDismissing = (translation >= self.translateForDismiss)
if afterRealseDismissing != self.afterReleaseDismissing {
self.afterReleaseDismissing = afterRealseDismissing
if self.hapticMoments.contains(.willDismissIfRelease) {
self.feedbackGenerator.impactOccurred()
if !self.workConfirmation {
if self.hapticMoments.contains(.willDismissIfRelease) {
self.feedbackGenerator.impactOccurred()
}
}
}
}
@@ -460,8 +511,6 @@ extension SPStorkPresentationController {
private func updateLayoutIndicator() {
self.indicatorView.style = .line
self.indicatorView.sizeToFit()
//self.indicatorView.frame.origin.y = 12
//self.indicatorView.center.x = presentedView.frame.width / 2
}
private func updateLayoutCloseButton() {
@@ -34,6 +34,7 @@ public final class SPStorkTransitioningDelegate: NSObject, UIViewControllerTrans
public var cornerRadius: CGFloat = 10
public var hapticMoments: [SPStorkHapticMoments] = [.willDismissIfRelease]
public weak var storkDelegate: SPStorkControllerDelegate? = nil
public weak var confirmDelegate: SPStorkControllerConfirmDelegate? = nil
public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
let controller = SPStorkPresentationController(presentedViewController: presented, presenting: presenting)
@@ -49,6 +50,7 @@ public final class SPStorkTransitioningDelegate: NSObject, UIViewControllerTrans
controller.hapticMoments = self.hapticMoments
controller.transitioningDelegate = self
controller.storkDelegate = self.storkDelegate
controller.confirmDelegate = self.confirmDelegate
return controller
}