diff --git a/SheetImagePicker.xcodeproj/project.pbxproj b/SheetImagePicker.xcodeproj/project.pbxproj index 0157842..3bc7a47 100644 --- a/SheetImagePicker.xcodeproj/project.pbxproj +++ b/SheetImagePicker.xcodeproj/project.pbxproj @@ -18,6 +18,8 @@ D610D2F6233945C0009EB06A /* SheetImagePicker.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D610D2D1233945AF009EB06A /* SheetImagePicker.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D610D2FD23394E00009EB06A /* SheetContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D610D2FC23394E00009EB06A /* SheetContainerViewController.swift */; }; D610D2FF23395975009EB06A /* Detent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D610D2FE23395975009EB06A /* Detent.swift */; }; + D6708861233ABF9100315DA9 /* SheetContainerPresentationAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6708860233ABF9100315DA9 /* SheetContainerPresentationAnimationController.swift */; }; + D6708863233AC8F600315DA9 /* SheetContainerDismissAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6708862233AC8F600315DA9 /* SheetContainerDismissAnimationController.swift */; }; D6B61D63233A748300809DE7 /* MathHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B61D62233A748300809DE7 /* MathHelpers.swift */; }; /* End PBXBuildFile section */ @@ -59,6 +61,8 @@ D610D2F0233945BB009EB06A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D610D2FC23394E00009EB06A /* SheetContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetContainerViewController.swift; sourceTree = ""; }; D610D2FE23395975009EB06A /* Detent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Detent.swift; sourceTree = ""; }; + D6708860233ABF9100315DA9 /* SheetContainerPresentationAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetContainerPresentationAnimationController.swift; sourceTree = ""; }; + D6708862233AC8F600315DA9 /* SheetContainerDismissAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetContainerDismissAnimationController.swift; sourceTree = ""; }; D6B61D62233A748300809DE7 /* MathHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MathHelpers.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -106,6 +110,8 @@ D610D2D4233945AF009EB06A /* SheetImagePicker.h */, D6B61D62233A748300809DE7 /* MathHelpers.swift */, D610D2FC23394E00009EB06A /* SheetContainerViewController.swift */, + D6708860233ABF9100315DA9 /* SheetContainerPresentationAnimationController.swift */, + D6708862233AC8F600315DA9 /* SheetContainerDismissAnimationController.swift */, D610D2FE23395975009EB06A /* Detent.swift */, D610D2D5233945AF009EB06A /* Info.plist */, ); @@ -249,6 +255,8 @@ files = ( D610D2FD23394E00009EB06A /* SheetContainerViewController.swift in Sources */, D610D2FF23395975009EB06A /* Detent.swift in Sources */, + D6708861233ABF9100315DA9 /* SheetContainerPresentationAnimationController.swift in Sources */, + D6708863233AC8F600315DA9 /* SheetContainerDismissAnimationController.swift in Sources */, D6B61D63233A748300809DE7 /* MathHelpers.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/SheetImagePicker/SheetContainerDismissAnimationController.swift b/SheetImagePicker/SheetContainerDismissAnimationController.swift new file mode 100644 index 0000000..678e10f --- /dev/null +++ b/SheetImagePicker/SheetContainerDismissAnimationController.swift @@ -0,0 +1,44 @@ +// +// SheetContainerDismissAnimationController.swift +// SheetImagePicker +// +// Created by Shadowfacts on 9/24/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import UIKit + +class SheetContainerDismissAnimationController: NSObject, UIViewControllerAnimatedTransitioning { + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return 0.35 + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + guard let fromVC = transitionContext.viewController(forKey: .from) as? SheetContainerViewController else { + fatalError() + } + + fromVC.view.alpha = 1.0 + fromVC.dimmingView.isHidden = true + + let dimmingView = UIView(frame: fromVC.view.frame) + dimmingView.backgroundColor = .systemGray + dimmingView.alpha = fromVC.dimmingView.alpha + + let container = transitionContext.containerView + container.addSubview(dimmingView) + container.addSubview(fromVC.view) + + let duration = transitionDuration(using: transitionContext) + UIView.animate(withDuration: duration, animations: { + dimmingView.alpha = 0 + fromVC.view.transform = CGAffineTransform(translationX: 0, y: fromVC.view.bounds.height) + }, completion: { (finished) in + dimmingView.removeFromSuperview() + + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + } + +} diff --git a/SheetImagePicker/SheetContainerPresentationAnimationController.swift b/SheetImagePicker/SheetContainerPresentationAnimationController.swift new file mode 100644 index 0000000..895f640 --- /dev/null +++ b/SheetImagePicker/SheetContainerPresentationAnimationController.swift @@ -0,0 +1,50 @@ +// +// SheetContainerPresentationAnimationController.swift +// SheetImagePicker +// +// Created by Shadowfacts on 9/24/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import UIKit + +class SheetContainerPresentationAnimationController: NSObject, UIViewControllerAnimatedTransitioning { + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return 0.35 + } + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + guard let toVC = transitionContext.viewController(forKey: .to) as? SheetContainerViewController else { + fatalError() + } + + toVC.dimmingView.isHidden = true + + let finalFrame = transitionContext.finalFrame(for: toVC) + + let dimmingView = UIView(frame: finalFrame) + dimmingView.backgroundColor = .systemGray + dimmingView.alpha = 0 + + let container = transitionContext.containerView + container.addSubview(dimmingView) + container.addSubview(toVC.view) + + toVC.view.transform = CGAffineTransform(translationX: 0, y: toVC.view.bounds.height) + + let duration = transitionDuration(using: transitionContext) + UIView.animate(withDuration: duration, animations: { + dimmingView.alpha = toVC.dimmingView.alpha + toVC.view.transform = .identity + }, completion: { (finished) in + dimmingView.removeFromSuperview() + toVC.dimmingView.isHidden = false + + toVC.view.frame = finalFrame + transitionContext.completeTransition(!transitionContext.transitionWasCancelled) + }) + + } + +} diff --git a/SheetImagePicker/SheetContainerViewController.swift b/SheetImagePicker/SheetContainerViewController.swift index c84c7e8..369cff2 100644 --- a/SheetImagePicker/SheetContainerViewController.swift +++ b/SheetImagePicker/SheetContainerViewController.swift @@ -49,6 +49,9 @@ public class SheetContainerViewController: UIViewController { self.content = content super.init(nibName: nil, bundle: nil) + + modalPresentationStyle = .custom + transitioningDelegate = self } required public init?(coder: NSCoder) { @@ -151,3 +154,11 @@ public class SheetContainerViewController: UIViewController { } +extension SheetContainerViewController: UIViewControllerTransitioningDelegate { + public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return SheetContainerPresentationAnimationController() + } + public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return SheetContainerDismissAnimationController() + } +} diff --git a/SheetImagePickerTest/Base.lproj/Main.storyboard b/SheetImagePickerTest/Base.lproj/Main.storyboard index 25a7638..b9471fd 100644 --- a/SheetImagePickerTest/Base.lproj/Main.storyboard +++ b/SheetImagePickerTest/Base.lproj/Main.storyboard @@ -1,7 +1,8 @@ - + + - + @@ -9,16 +10,30 @@ - + - + - + + + + + + + + + diff --git a/SheetImagePickerTest/ViewController.swift b/SheetImagePickerTest/ViewController.swift index 3a90937..ccccf85 100644 --- a/SheetImagePickerTest/ViewController.swift +++ b/SheetImagePickerTest/ViewController.swift @@ -15,38 +15,25 @@ class ViewController: UIViewController { super.viewDidLoad() // Do any additional setup after loading the view. view.backgroundColor = .green - + } + + @IBAction func buttonPressed(_ sender: Any) { let content = UIViewController() content.view.translatesAutoresizingMaskIntoConstraints = false content.view.backgroundColor = .red let sheet = SheetContainerViewController(content: content) sheet.delegate = self sheet.detents = [.bottom, .middle, .top] -// sheet.view.backgroundColor = .blue - addChild(sheet) - sheet.didMove(toParent: self) - view.addSubview(sheet.view) - NSLayoutConstraint.activate([ - sheet.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), - sheet.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), - sheet.view.topAnchor.constraint(equalTo: view.topAnchor), - sheet.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) - ]) + present(sheet, animated: true) } - + } extension ViewController: SheetContainerViewControllerDelegate { func sheetContainer(_ sheetContainer: SheetContainerViewController, willSnapToDetent detent: Detent) -> Bool { if detent == .bottom { - UIView.animate(withDuration: 0.35, animations: { - sheetContainer.view.transform = CGAffineTransform(translationX: 0, y: sheetContainer.view.bounds.height) - }, completion: { (finished) in - sheetContainer.removeFromParent() - sheetContainer.didMove(toParent: nil) - sheetContainer.view.removeFromSuperview() - }) + sheetContainer.dismiss(animated: true) return false } return true