Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79d64599d0 | |||
| 854ab2aef2 | |||
| 04c4929e7d | |||
| 6e4e9713c3 | |||
| e37c43c8f3 | |||
| 001536c835 |
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
@@ -28,6 +28,7 @@ public struct SPStorkController {
|
||||
if let presentationController = controller.presentationController as? SPStorkPresentationController {
|
||||
let translation = -(scrollView.contentOffset.y + scrollView.contentInset.top)
|
||||
if translation >= 0 {
|
||||
if controller.isBeingPresented { return }
|
||||
scrollView.subviews.forEach {
|
||||
$0.transform = CGAffineTransform(translationX: 0, y: -translation)
|
||||
}
|
||||
|
||||
+14
-10
@@ -23,11 +23,13 @@ import UIKit
|
||||
|
||||
class SPStorkPresentationController: UIPresentationController, UIGestureRecognizerDelegate {
|
||||
|
||||
var isSwipeToDismissEnabled: Bool = true
|
||||
var isTapAroundToDismissEnabled: Bool = true
|
||||
var swipeToDismissEnabled: Bool = true
|
||||
var tapAroundToDismissEnabled: Bool = true
|
||||
var showIndicator: Bool = true
|
||||
var indicatorColor: UIColor = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1)
|
||||
var customHeight: CGFloat? = nil
|
||||
var translateForDismiss: CGFloat = 240
|
||||
|
||||
var transitioningDelegate: SPStorkTransitioningDelegate?
|
||||
|
||||
var pan: UIPanGestureRecognizer?
|
||||
@@ -84,7 +86,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
|
||||
|
||||
if self.showIndicator {
|
||||
self.indicatorView.color = self.indicatorColor
|
||||
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.handleTap))
|
||||
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction))
|
||||
tap.cancelsTouchesInView = false
|
||||
self.indicatorView.addGestureRecognizer(tap)
|
||||
presentedView.addSubview(self.indicatorView)
|
||||
@@ -169,13 +171,13 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
|
||||
self.snapshotViewContainer.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
|
||||
self.updateSnapshotAspectRatio()
|
||||
|
||||
if self.isTapAroundToDismissEnabled {
|
||||
self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.handleTap))
|
||||
if self.tapAroundToDismissEnabled {
|
||||
self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction))
|
||||
self.tap?.cancelsTouchesInView = false
|
||||
self.snapshotViewContainer.addGestureRecognizer(self.tap!)
|
||||
}
|
||||
|
||||
if self.isSwipeToDismissEnabled {
|
||||
if self.swipeToDismissEnabled {
|
||||
self.pan = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan))
|
||||
self.pan!.delegate = self
|
||||
self.pan!.maximumNumberOfTouches = 1
|
||||
@@ -184,7 +186,9 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
|
||||
}
|
||||
}
|
||||
|
||||
@objc func handleTap() {
|
||||
@objc func dismissAction() {
|
||||
self.presentingViewController.view.endEditing(true)
|
||||
self.presentedViewController.view.endEditing(true)
|
||||
self.presentedViewController.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@@ -266,7 +270,7 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
|
||||
extension SPStorkPresentationController {
|
||||
|
||||
@objc func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
|
||||
guard gestureRecognizer.isEqual(pan), self.isSwipeToDismissEnabled else { return }
|
||||
guard gestureRecognizer.isEqual(self.pan), self.swipeToDismissEnabled else { return }
|
||||
|
||||
switch gestureRecognizer.state {
|
||||
case .began:
|
||||
@@ -278,7 +282,7 @@ extension SPStorkPresentationController {
|
||||
gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: containerView)
|
||||
case .changed:
|
||||
self.workGester = true
|
||||
if self.isSwipeToDismissEnabled {
|
||||
if self.swipeToDismissEnabled {
|
||||
let translation = gestureRecognizer.translation(in: presentedView)
|
||||
self.updatePresentedViewForTranslation(inVerticalDirection: translation.y)
|
||||
} else {
|
||||
@@ -287,7 +291,7 @@ extension SPStorkPresentationController {
|
||||
case .ended:
|
||||
self.workGester = false
|
||||
let translation = gestureRecognizer.translation(in: presentedView).y
|
||||
if translation >= 240 {
|
||||
if translation >= self.translateForDismiss {
|
||||
presentedViewController.dismiss(animated: true, completion: nil)
|
||||
} else {
|
||||
self.indicatorView.style = .arrow
|
||||
|
||||
+7
-1
@@ -31,10 +31,16 @@ final class SPStorkPresentingAnimationController: NSObject, UIViewControllerAnim
|
||||
|
||||
let containerView = transitionContext.containerView
|
||||
containerView.addSubview(presentedViewController.view)
|
||||
presentedViewController.view.frame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
|
||||
|
||||
//presentedViewController.view.frame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
|
||||
|
||||
let finalFrameForPresentedView = transitionContext.finalFrame(for: presentedViewController)
|
||||
|
||||
// NEW FRAMING: Testing now. Maybe correct. If remove it lines, init frame of controller will be equal container (not stork)
|
||||
presentedViewController.view.frame = finalFrameForPresentedView
|
||||
presentedViewController.view.frame.origin.y = containerView.bounds.height
|
||||
// END NEW.
|
||||
|
||||
UIView.animate(
|
||||
withDuration: transitionDuration(using: transitionContext),
|
||||
delay: 0,
|
||||
|
||||
+6
-4
@@ -23,19 +23,21 @@ import UIKit
|
||||
|
||||
public final class SPStorkTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
|
||||
|
||||
public var isSwipeToDismissEnabled: Bool = true
|
||||
public var isTapAroundToDismissEnabled: Bool = true
|
||||
public var swipeToDismissEnabled: Bool = true
|
||||
public var tapAroundToDismissEnabled: Bool = true
|
||||
public var showIndicator: Bool = true
|
||||
public var indicatorColor: UIColor = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1)
|
||||
public var customHeight: CGFloat? = nil
|
||||
public var translateForDismiss: CGFloat = 240
|
||||
|
||||
public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
|
||||
let controller = SPStorkPresentationController(presentedViewController: presented, presenting: presenting)
|
||||
controller.isSwipeToDismissEnabled = self.isSwipeToDismissEnabled
|
||||
controller.isTapAroundToDismissEnabled = self.isTapAroundToDismissEnabled
|
||||
controller.swipeToDismissEnabled = self.swipeToDismissEnabled
|
||||
controller.tapAroundToDismissEnabled = self.tapAroundToDismissEnabled
|
||||
controller.showIndicator = self.showIndicator
|
||||
controller.indicatorColor = self.indicatorColor
|
||||
controller.customHeight = self.customHeight
|
||||
controller.translateForDismiss = self.translateForDismiss
|
||||
controller.transitioningDelegate = self
|
||||
return controller
|
||||
}
|
||||
|
||||
+3
-1
@@ -29,10 +29,12 @@ extension UIViewController {
|
||||
&& presentingViewController != nil
|
||||
}
|
||||
|
||||
public func presentAsStork(_ controller: UIViewController, complection: (() -> Void)? = nil) {
|
||||
public func presentAsStork(_ controller: UIViewController, height: CGFloat? = nil, complection: (() -> Void)? = nil) {
|
||||
let transitionDelegate = SPStorkTransitioningDelegate()
|
||||
transitionDelegate.customHeight = height
|
||||
controller.transitioningDelegate = transitionDelegate
|
||||
controller.modalPresentationStyle = .custom
|
||||
controller.modalPresentationCapturesStatusBarAppearance = true
|
||||
self.present(controller, animated: true, completion: complection)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,16 @@ public class SPButton: UIButton {
|
||||
self.round()
|
||||
}
|
||||
}
|
||||
|
||||
public func set(enable: Bool, animatable: Bool) {
|
||||
self.isEnabled = enable
|
||||
if animatable {
|
||||
SPAnimation.animate(0.3, animations: {
|
||||
self.alpha = enable ? 1 : 0.6
|
||||
})
|
||||
} else {
|
||||
self.alpha = enable ? 1 : 0.6
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ public class SPFakeBarView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
public var closeButton: closeButtonPlace = .none {
|
||||
public var closeButtonPossition: CloseButtonPosition = .none {
|
||||
didSet {
|
||||
self.leftButton.titleLabel?.font = UIFont.system(type: .Regular, size: 17)
|
||||
self.rightButton.titleLabel?.font = UIFont.system(type: .Regular, size: 17)
|
||||
switch self.closeButton {
|
||||
switch self.closeButtonPossition {
|
||||
case .left:
|
||||
self.leftButton.titleLabel?.font = UIFont.system(type: .DemiBold, size: 17)
|
||||
case .right:
|
||||
@@ -145,7 +145,7 @@ public class SPFakeBarView: UIView {
|
||||
self.rightButton.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
|
||||
self.rightButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -12).isActive = true
|
||||
|
||||
self.closeButton = .none
|
||||
self.closeButtonPossition = .none
|
||||
|
||||
self.setContraints()
|
||||
self.updateStyle()
|
||||
@@ -215,7 +215,7 @@ public class SPFakeBarView: UIView {
|
||||
self.updateConstraints()
|
||||
}
|
||||
|
||||
public enum closeButtonPlace {
|
||||
public enum CloseButtonPosition {
|
||||
case left
|
||||
case right
|
||||
case none
|
||||
|
||||
@@ -51,6 +51,7 @@ let controller = UIViewController()
|
||||
let transitionDelegate = SPStorkTransitioningDelegate()
|
||||
controller.transitioningDelegate = transitionDelegate
|
||||
controller.modalPresentationStyle = .custom
|
||||
controller.modalPresentationCapturesStatusBarAppearance = true
|
||||
self.present(controller, animated: true, completion: nil)
|
||||
```
|
||||
|
||||
@@ -62,6 +63,10 @@ controller.transitioningDelegate = SPStorkTransitioningDelegate()
|
||||
|
||||
You will get an error about weak property.
|
||||
|
||||
### Need help
|
||||
|
||||
Please, see [this issue](https://github.com/IvanVorobei/SPStorkController/issues/30). Bug with work table. Need help for fix it and update project.
|
||||
|
||||
### Video Tutorial
|
||||
|
||||
You can see how to use `SPStorkController` and how to customize it [in this video](https://youtu.be/wOTNGswT2-0). For English speakers I’ve added subtitles, don’t forget to turn them on:
|
||||
@@ -82,22 +87,27 @@ class ModalViewController: UIViewController {
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return .lightContent
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.modalPresentationCapturesStatusBarAppearance = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- Parameter `customHeight` sets custom height for modal controller. Default is `nil`:
|
||||
```swift
|
||||
transitionDelegate.customHeight = 350
|
||||
```
|
||||
|
||||
- Parameter `swipeToDismissEnabled` enables dismissal by swipe gesture. Default is `true`:
|
||||
|
||||
```swift
|
||||
transitionDelegate.swipeToDismissEnabled = true
|
||||
```
|
||||
|
||||
- Parameter `translateForDismiss` sets how much need to swipe down to close the controller. Work only if `swipeToDismissEnabled` is true. Default is `240`:
|
||||
```swift
|
||||
transitionDelegate.translateForDismiss = 100
|
||||
```
|
||||
|
||||
- Parameter `tapAroundToDismissEnabled` enables dismissal by tapping parent controller. Default is `true`:
|
||||
|
||||
```swift
|
||||
@@ -114,16 +124,6 @@ transitionDelegate.showIndicator = true
|
||||
transitionDelegate.indicatorColor = UIColor.white
|
||||
```
|
||||
|
||||
- Parameter `customHeight` sets custom height for modal controller. Default is `nil`:
|
||||
```swift
|
||||
transitionDelegate.customHeight = 350
|
||||
```
|
||||
|
||||
- Parameter `translateForDismiss` sets how much need to swipe down to close the controller. Work only if `swipeToDismissEnabled` is true. Default is `240`:
|
||||
```swift
|
||||
transitionDelegate.translateForDismiss = 100
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
The project uses a snapshot of the screen in order to avoid compatibility and customization issues. Before controller presentation, a snapshot of the parent view is made, and size and position are changed for the snapshot. Sometimes you will need to update the screenshot of the parent view, for that use static func:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SPStorkController"
|
||||
s.version = "1.4.2"
|
||||
s.version = "1.4.5"
|
||||
s.summary = "Modal controller as mail or Apple music application"
|
||||
s.homepage = "https://github.com/IvanVorobei/SPStorkController"
|
||||
s.source = { :git => "https://github.com/IvanVorobei/SPStorkController.git", :tag => s.version }
|
||||
|
||||
@@ -28,6 +28,7 @@ public struct SPStorkController {
|
||||
if let presentationController = controller.presentationController as? SPStorkPresentationController {
|
||||
let translation = -(scrollView.contentOffset.y + scrollView.contentInset.top)
|
||||
if translation >= 0 {
|
||||
if controller.isBeingPresented { return }
|
||||
scrollView.subviews.forEach {
|
||||
$0.transform = CGAffineTransform(translationX: 0, y: -translation)
|
||||
}
|
||||
|
||||
@@ -187,6 +187,8 @@ class SPStorkPresentationController: UIPresentationController, UIGestureRecogniz
|
||||
}
|
||||
|
||||
@objc func dismissAction() {
|
||||
self.presentingViewController.view.endEditing(true)
|
||||
self.presentedViewController.view.endEditing(true)
|
||||
self.presentedViewController.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,16 @@ final class SPStorkPresentingAnimationController: NSObject, UIViewControllerAnim
|
||||
|
||||
let containerView = transitionContext.containerView
|
||||
containerView.addSubview(presentedViewController.view)
|
||||
presentedViewController.view.frame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
|
||||
|
||||
//presentedViewController.view.frame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
|
||||
|
||||
let finalFrameForPresentedView = transitionContext.finalFrame(for: presentedViewController)
|
||||
|
||||
// NEW FRAMING: Testing now. Maybe correct. If remove it lines, init frame of controller will be equal container (not stork)
|
||||
presentedViewController.view.frame = finalFrameForPresentedView
|
||||
presentedViewController.view.frame.origin.y = containerView.bounds.height
|
||||
// END NEW.
|
||||
|
||||
UIView.animate(
|
||||
withDuration: transitionDuration(using: transitionContext),
|
||||
delay: 0,
|
||||
|
||||
@@ -29,10 +29,12 @@ extension UIViewController {
|
||||
&& presentingViewController != nil
|
||||
}
|
||||
|
||||
public func presentAsStork(_ controller: UIViewController, complection: (() -> Void)? = nil) {
|
||||
public func presentAsStork(_ controller: UIViewController, height: CGFloat? = nil, complection: (() -> Void)? = nil) {
|
||||
let transitionDelegate = SPStorkTransitioningDelegate()
|
||||
transitionDelegate.customHeight = height
|
||||
controller.transitioningDelegate = transitionDelegate
|
||||
controller.modalPresentationStyle = .custom
|
||||
controller.modalPresentationCapturesStatusBarAppearance = true
|
||||
self.present(controller, animated: true, completion: complection)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user