diff --git a/Example/stork-controller.xcodeproj/project.xcworkspace/xcuserdata/ivanvorobei.xcuserdatad/UserInterfaceState.xcuserstate b/Example/stork-controller.xcodeproj/project.xcworkspace/xcuserdata/ivanvorobei.xcuserdatad/UserInterfaceState.xcuserstate index e8b3611..ad1eef1 100644 Binary files a/Example/stork-controller.xcodeproj/project.xcworkspace/xcuserdata/ivanvorobei.xcuserdatad/UserInterfaceState.xcuserstate and b/Example/stork-controller.xcodeproj/project.xcworkspace/xcuserdata/ivanvorobei.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Example/stork-controller/Frameworks/SPStorkController/SPStorkController.swift b/Example/stork-controller/Frameworks/SPStorkController/SPStorkController.swift index 11704c7..af68073 100755 --- a/Example/stork-controller/Frameworks/SPStorkController/SPStorkController.swift +++ b/Example/stork-controller/Frameworks/SPStorkController/SPStorkController.swift @@ -35,32 +35,9 @@ public enum SPStorkController { presentationController.setIndicator(style: scrollView.isTracking ? .line : .arrow) if translation >= presentationController.translateForDismiss * 0.4 { if !scrollView.isTracking && !scrollView.isDragging { - - let dismiss = { - presentationController.presentedViewController.dismiss(animated: true, completion: { - presentationController.storkDelegate?.didDismissStorkBySwipe?() - }) - } - - guard let confirmDelegate = presentationController.confirmDelegate else { - dismiss() - return - } - - if presentationController.workConfirmation { return } - - if confirmDelegate.needConfirm { - presentationController.workConfirmation = true - confirmDelegate.confirm({ (isConfirmed) in - presentationController.workConfirmation = false - if isConfirmed { - dismiss() - } - }) - } else { - dismiss() - } - + presentationController.dismissWithConfirmation(prepare: nil, completion: { + presentationController.storkDelegate?.didDismissStorkBySwipe?() + }) return } } diff --git a/Example/stork-controller/Frameworks/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift b/Example/stork-controller/Frameworks/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift index 4454f71..65b6944 100755 --- a/Example/stork-controller/Frameworks/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift +++ b/Example/stork-controller/Frameworks/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift @@ -50,7 +50,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz private var snapshotViewTopConstraint: NSLayoutConstraint? private var snapshotViewWidthConstraint: NSLayoutConstraint? private var snapshotViewAspectRatioConstraint: NSLayoutConstraint? - + var workConfirmation: Bool = false private var workGester: Bool = false private var startDismissing: Bool = false @@ -107,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) @@ -122,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() @@ -209,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!) } @@ -223,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) @@ -314,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 } @@ -337,7 +379,7 @@ extension SPStorkPresentationController { self.workGester = false let translation = gestureRecognizer.translation(in: presentedView).y - let returnToDefault = { + let toDefault = { self.indicatorView.style = .arrow UIView.animate( withDuration: 0.6, @@ -352,36 +394,12 @@ extension SPStorkPresentationController { }) } - let dismissBySwipe = { - self.presentedViewController.dismiss(animated: true, completion: { + if translation >= self.translateForDismiss { + self.dismissWithConfirmation(prepare: toDefault, completion: { self.storkDelegate?.didDismissStorkBySwipe?() }) - } - - if translation >= self.translateForDismiss { - - guard let confirmDelegate = self.confirmDelegate else { - dismissBySwipe() - return - } - - if self.workConfirmation { return } - - if confirmDelegate.needConfirm { - returnToDefault() - self.workConfirmation = true - confirmDelegate.confirm({ (isConfirmed) in - self.workConfirmation = false - self.afterReleaseDismissing = false - if isConfirmed { - dismissBySwipe() - } - }) - } else { - dismissBySwipe() - } } else { - returnToDefault() + toDefault() } default: break @@ -432,7 +450,7 @@ extension SPStorkPresentationController { let elasticThreshold: CGFloat = 120 let translationFactor: CGFloat = 1 / 2 - + if translation >= 0 { let translationForModal: CGFloat = { if translation >= elasticThreshold { diff --git a/Example/stork-controller/ModalTableViewController.swift b/Example/stork-controller/ModalTableViewController.swift index bffac49..e230ff5 100644 --- a/Example/stork-controller/ModalTableViewController.swift +++ b/Example/stork-controller/ModalTableViewController.swift @@ -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.") + }) + } } } @@ -86,7 +90,6 @@ extension ModalTableViewController: SPStorkControllerConfirmDelegate { } func confirm(_ completion: @escaping (Bool) -> ()) { - print("confirm") let alertController = UIAlertController(title: "Need dismiss?", message: "It test confirm option for SPStorkController", preferredStyle: .actionSheet) alertController.addDestructiveAction(title: "Confirm", complection: { completion(true) diff --git a/Example/stork-controller/ModalViewController.swift b/Example/stork-controller/ModalViewController.swift index 65875e0..1b40986 100644 --- a/Example/stork-controller/ModalViewController.swift +++ b/Example/stork-controller/ModalViewController.swift @@ -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) { @@ -35,7 +39,7 @@ class ModalViewController: UIViewController { extension ModalViewController: SPStorkControllerConfirmDelegate { var needConfirm: Bool { - return false + return true } func confirm(_ completion: @escaping (Bool) -> ()) { diff --git a/SPStorkController.podspec b/SPStorkController.podspec index be8e19d..140053b 100644 --- a/SPStorkController.podspec +++ b/SPStorkController.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "SPStorkController" - s.version = "1.7.1" + 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 } diff --git a/Source/SPStorkController/SPStorkController.swift b/Source/SPStorkController/SPStorkController.swift index 11704c7..af68073 100755 --- a/Source/SPStorkController/SPStorkController.swift +++ b/Source/SPStorkController/SPStorkController.swift @@ -35,32 +35,9 @@ public enum SPStorkController { presentationController.setIndicator(style: scrollView.isTracking ? .line : .arrow) if translation >= presentationController.translateForDismiss * 0.4 { if !scrollView.isTracking && !scrollView.isDragging { - - let dismiss = { - presentationController.presentedViewController.dismiss(animated: true, completion: { - presentationController.storkDelegate?.didDismissStorkBySwipe?() - }) - } - - guard let confirmDelegate = presentationController.confirmDelegate else { - dismiss() - return - } - - if presentationController.workConfirmation { return } - - if confirmDelegate.needConfirm { - presentationController.workConfirmation = true - confirmDelegate.confirm({ (isConfirmed) in - presentationController.workConfirmation = false - if isConfirmed { - dismiss() - } - }) - } else { - dismiss() - } - + presentationController.dismissWithConfirmation(prepare: nil, completion: { + presentationController.storkDelegate?.didDismissStorkBySwipe?() + }) return } } diff --git a/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift b/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift index 4454f71..65b6944 100755 --- a/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift +++ b/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift @@ -50,7 +50,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz private var snapshotViewTopConstraint: NSLayoutConstraint? private var snapshotViewWidthConstraint: NSLayoutConstraint? private var snapshotViewAspectRatioConstraint: NSLayoutConstraint? - + var workConfirmation: Bool = false private var workGester: Bool = false private var startDismissing: Bool = false @@ -107,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) @@ -122,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() @@ -209,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!) } @@ -223,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) @@ -314,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 } @@ -337,7 +379,7 @@ extension SPStorkPresentationController { self.workGester = false let translation = gestureRecognizer.translation(in: presentedView).y - let returnToDefault = { + let toDefault = { self.indicatorView.style = .arrow UIView.animate( withDuration: 0.6, @@ -352,36 +394,12 @@ extension SPStorkPresentationController { }) } - let dismissBySwipe = { - self.presentedViewController.dismiss(animated: true, completion: { + if translation >= self.translateForDismiss { + self.dismissWithConfirmation(prepare: toDefault, completion: { self.storkDelegate?.didDismissStorkBySwipe?() }) - } - - if translation >= self.translateForDismiss { - - guard let confirmDelegate = self.confirmDelegate else { - dismissBySwipe() - return - } - - if self.workConfirmation { return } - - if confirmDelegate.needConfirm { - returnToDefault() - self.workConfirmation = true - confirmDelegate.confirm({ (isConfirmed) in - self.workConfirmation = false - self.afterReleaseDismissing = false - if isConfirmed { - dismissBySwipe() - } - }) - } else { - dismissBySwipe() - } } else { - returnToDefault() + toDefault() } default: break @@ -432,7 +450,7 @@ extension SPStorkPresentationController { let elasticThreshold: CGFloat = 120 let translationFactor: CGFloat = 1 / 2 - + if translation >= 0 { let translationForModal: CGFloat = { if translation >= elasticThreshold {