Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ee5f9ee9de | |||
| 8348cd6396 |
BIN
Binary file not shown.
@@ -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()
|
||||
}
|
||||
|
||||
self.dismissWithConfirmation(controller: controller, completion: {
|
||||
presentationController.storkDelegate?.didDismissStorkBySwipe?()
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -81,6 +58,14 @@ public enum SPStorkController {
|
||||
}
|
||||
}
|
||||
|
||||
static public func dismissWithConfirmation(controller: UIViewController, completion: (()->())?) {
|
||||
if let controller = self.presentationController(for: controller) {
|
||||
controller.dismissWithConfirmation(prepare: nil, completion: {
|
||||
print("Custom completion for confirmation. Confirmation is optional.")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
static public var topScrollIndicatorInset: CGFloat {
|
||||
return 6
|
||||
}
|
||||
|
||||
+60
-42
@@ -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 {
|
||||
|
||||
@@ -49,7 +49,7 @@ class ModalTableViewController: UIViewController {
|
||||
}
|
||||
|
||||
@objc func dismissAction() {
|
||||
self.dismiss()
|
||||
SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,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)
|
||||
|
||||
@@ -20,7 +20,7 @@ class ModalViewController: UIViewController {
|
||||
}
|
||||
|
||||
@objc func dismissAction() {
|
||||
self.dismiss()
|
||||
SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@@ -35,7 +35,7 @@ class ModalViewController: UIViewController {
|
||||
extension ModalViewController: SPStorkControllerConfirmDelegate {
|
||||
|
||||
var needConfirm: Bool {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
func confirm(_ completion: @escaping (Bool) -> ()) {
|
||||
|
||||
@@ -277,7 +277,7 @@ Please, also use `SPStorkController.scrollViewDidScroll` function in scroll dele
|
||||
|
||||
### Confirm
|
||||
|
||||
For confirm closing by swipe, use `SPStorkControllerConfirmDelegate`. Implenet protocol:
|
||||
For confirm closing by swipe, tap around, close button and indicator use `SPStorkControllerConfirmDelegate`. Implenet protocol:
|
||||
|
||||
```swift
|
||||
@objc public protocol SPStorkControllerConfirmDelegate: class {
|
||||
@@ -288,7 +288,15 @@ For confirm closing by swipe, use `SPStorkControllerConfirmDelegate`. Implenet p
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
and set `confirmDelegate` property to object, which protocol impleneted. Function `confirm` call if `needConfirm` return true. Pass `isConfirmed` with result. Best options use `UIAlertController` with `.actionSheet` style for confirmation.
|
||||
|
||||
If you use custom buttons, in the target use this code:
|
||||
|
||||
```swift
|
||||
SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
|
||||
```
|
||||
|
||||
It call `confirm` func and check result of confirmation. See example project for more details.
|
||||
|
||||
### Delegate
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Pod::Spec.new do |s|
|
||||
|
||||
s.name = "SPStorkController"
|
||||
s.version = "1.7.1"
|
||||
s.version = "1.7.4"
|
||||
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 }
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
self.dismissWithConfirmation(controller: controller, completion: {
|
||||
presentationController.storkDelegate?.didDismissStorkBySwipe?()
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -81,6 +58,14 @@ public enum SPStorkController {
|
||||
}
|
||||
}
|
||||
|
||||
static public func dismissWithConfirmation(controller: UIViewController, completion: (()->())?) {
|
||||
if let controller = self.presentationController(for: controller) {
|
||||
controller.dismissWithConfirmation(prepare: nil, completion: {
|
||||
print("Custom completion for confirmation. Confirmation is optional.")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
static public var topScrollIndicatorInset: CGFloat {
|
||||
return 6
|
||||
}
|
||||
|
||||
+60
-42
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user