├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .travis.yml ├── BonsaiController.podspec ├── BonsaiController ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── BonsaiController.swift │ ├── BubbleTransition.swift │ └── SlideInTransition.swift ├── Example ├── BonsaiController.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── BonsaiController-Example.xcscheme ├── BonsaiController.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── BonsaiController │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── BonsaiController_Example-Bridging-Header.h │ ├── CollectionView Example │ │ ├── CollectionViewCell.swift │ │ └── CollectionViewController.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── icon_1024@1x.png │ │ │ ├── icon_20@1x.png │ │ │ ├── icon_20@2x.png │ │ │ ├── icon_20@3x.png │ │ │ ├── icon_29@1x.png │ │ │ ├── icon_29@2x.png │ │ │ ├── icon_29@3x.png │ │ │ ├── icon_40@1x.png │ │ │ ├── icon_40@2x.png │ │ │ ├── icon_40@3x.png │ │ │ ├── icon_60@2x.png │ │ │ ├── icon_60@3x.png │ │ │ ├── icon_76@1x.png │ │ │ ├── icon_76@2x.png │ │ │ └── icon_83.5@2x.png │ │ ├── Contents.json │ │ ├── bg.imageset │ │ │ ├── Contents.json │ │ │ └── Re_Bb@3x.pdf │ │ └── leaf.imageset │ │ │ ├── Contents.json │ │ │ └── leaf@3x.pdf │ ├── Info.plist │ ├── Objective-C Example │ │ ├── ObjectiveCViewController.h │ │ └── ObjectiveCViewController.m │ ├── SmallViewController.swift │ ├── Utilities │ │ ├── BonsaiFullScreenPopUtility.swift │ │ ├── BonsaiNotificationUtility.swift │ │ └── BonsaiPopupUtility.swift │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ ├── BonsaiController.podspec.json │ │ └── CustomSizeController.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── BonsaiController │ │ ├── BonsaiController-dummy.m │ │ ├── BonsaiController-prefix.pch │ │ ├── BonsaiController-umbrella.h │ │ ├── BonsaiController.modulemap │ │ ├── BonsaiController.xcconfig │ │ └── Info.plist │ │ ├── Pods-BonsaiController_Example │ │ ├── Info.plist │ │ ├── Pods-BonsaiController_Example-acknowledgements.markdown │ │ ├── Pods-BonsaiController_Example-acknowledgements.plist │ │ ├── Pods-BonsaiController_Example-dummy.m │ │ ├── Pods-BonsaiController_Example-frameworks.sh │ │ ├── Pods-BonsaiController_Example-resources.sh │ │ ├── Pods-BonsaiController_Example-umbrella.h │ │ ├── Pods-BonsaiController_Example.debug.xcconfig │ │ ├── Pods-BonsaiController_Example.modulemap │ │ └── Pods-BonsaiController_Example.release.xcconfig │ │ └── Pods-BonsaiController_Tests │ │ ├── Info.plist │ │ ├── Pods-BonsaiController_Tests-acknowledgements.markdown │ │ ├── Pods-BonsaiController_Tests-acknowledgements.plist │ │ ├── Pods-BonsaiController_Tests-dummy.m │ │ ├── Pods-BonsaiController_Tests-frameworks.sh │ │ ├── Pods-BonsaiController_Tests-resources.sh │ │ ├── Pods-BonsaiController_Tests-umbrella.h │ │ ├── Pods-BonsaiController_Tests.debug.xcconfig │ │ ├── Pods-BonsaiController_Tests.modulemap │ │ └── Pods-BonsaiController_Tests.release.xcconfig └── Tests │ ├── Info.plist │ └── Tests.swift ├── LICENSE ├── Package.swift ├── README.md ├── _Pods.xcodeproj └── _config.yml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/CustomSizeController.xcworkspace -scheme CustomSizeController-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /BonsaiController.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run ` ' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'BonsaiController' 11 | s.version = '7.0.2' 12 | s.summary = '🌲 Bonsai makes custom frame size and transition animation to any view controller' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | Add the ability to change custom frame size with cool transition animation to any view controller. 22 | DESC 23 | 24 | s.homepage = 'https://github.com/rishi420/Bonsai' 25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' 26 | s.license = { :type => 'MIT', :file => 'LICENSE' } 27 | s.author = { 'Warif Akhand Rishi' => 'rishi420@gmail.com' } 28 | s.source = { :git => 'https://github.com/rishi420/Bonsai.git', :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | s.swift_version = '5' 31 | 32 | s.ios.deployment_target = '9.3' 33 | 34 | s.source_files = 'BonsaiController/Classes/**/*' 35 | 36 | # s.resource_bundles = { 37 | # 'BonsaiController' => ['BonsaiController/Assets/*.png'] 38 | # } 39 | 40 | # s.public_header_files = 'Pod/Classes/**/*.h' 41 | # s.frameworks = 'UIKit', 'MapKit' 42 | # s.dependency 'AFNetworking', '~> 2.3' 43 | end 44 | -------------------------------------------------------------------------------- /BonsaiController/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/BonsaiController/Assets/.gitkeep -------------------------------------------------------------------------------- /BonsaiController/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/BonsaiController/Classes/.gitkeep -------------------------------------------------------------------------------- /BonsaiController/Classes/BonsaiController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BonsaiController.swift 3 | // BonsaiController 4 | // 5 | // Created by Warif Akhand Rishi on 22/5/18. 6 | // Copyright © 2018 Warif Akhand Rishi. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @objc 12 | public protocol BonsaiControllerDelegate: UIViewControllerTransitioningDelegate { 13 | 14 | /// Returns a frame for presented viewController on containerView 15 | /// 16 | /// - Parameter: containerViewFrame 17 | 18 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect 19 | 20 | //@objc(presentationControllerForPresentedViewController:presentingViewController:sourceViewController:) 21 | //func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? 22 | @objc optional func didDismiss() 23 | } 24 | 25 | @objc 26 | public protocol BonsaiTransitionProperties { 27 | var duration: TimeInterval {get set} 28 | var springWithDamping: CGFloat {get set} 29 | var isDisabledDismissAnimation: Bool {get set} 30 | } 31 | 32 | @objc 33 | public class BonsaiController: UIPresentationController, BonsaiTransitionProperties { 34 | 35 | public var duration: TimeInterval = 0.4 36 | public var springWithDamping: CGFloat = 0.8 37 | public var isDisabledDismissAnimation: Bool = false 38 | @objc public var isDisabledTapOutside: Bool = false 39 | 40 | /// Availabel only for slide in transition in swift 41 | @nonobjc public var dismissDirection: Direction? = nil 42 | 43 | weak public var sizeDelegate: BonsaiControllerDelegate? 44 | 45 | private var originView: UIView? // For Bubble transition 46 | private var fromDirection: Direction! // For slide Transition 47 | private var blurEffectView: UIVisualEffectView! 48 | private var blurEffectStyle: UIBlurEffect.Style? 49 | private var backgroundColor: UIColor? 50 | 51 | @objc 52 | convenience public init(fromDirection: Direction, blurEffectStyle: UIBlurEffect.Style, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { 53 | self.init(presentedViewController: presentedViewController, presenting: nil) 54 | 55 | self.fromDirection = fromDirection 56 | self.sizeDelegate = delegate 57 | self.blurEffectStyle = blurEffectStyle 58 | setup(presentedViewController: presentedViewController) 59 | } 60 | 61 | 62 | @objc 63 | convenience public init(fromDirection: Direction, backgroundColor: UIColor, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { 64 | self.init(presentedViewController: presentedViewController, presenting: nil) 65 | 66 | self.fromDirection = fromDirection 67 | self.sizeDelegate = delegate 68 | self.backgroundColor = backgroundColor 69 | setup(presentedViewController: presentedViewController) 70 | } 71 | 72 | @objc 73 | convenience public init(fromView: UIView, blurEffectStyle: UIBlurEffect.Style, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { 74 | self.init(presentedViewController: presentedViewController, presenting: nil) 75 | 76 | self.originView = fromView 77 | self.sizeDelegate = delegate 78 | self.blurEffectStyle = blurEffectStyle 79 | setup(presentedViewController: presentedViewController) 80 | } 81 | 82 | @objc 83 | convenience public init(fromView: UIView, backgroundColor: UIColor, presentedViewController: UIViewController, delegate: BonsaiControllerDelegate?) { 84 | self.init(presentedViewController: presentedViewController, presenting: nil) 85 | 86 | self.originView = fromView 87 | self.sizeDelegate = delegate 88 | self.backgroundColor = backgroundColor 89 | setup(presentedViewController: presentedViewController) 90 | } 91 | 92 | override private init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) { 93 | super.init(presentedViewController: presentedViewController, presenting: presentingViewController) 94 | } 95 | 96 | @objc public func dismiss() { 97 | presentedViewController.dismiss(animated: true, completion: nil) 98 | } 99 | 100 | private func setup(presentedViewController: UIViewController) { 101 | 102 | var blurEffect: UIBlurEffect? 103 | if let blurEffectStyle = blurEffectStyle { 104 | blurEffect = UIBlurEffect(style: blurEffectStyle) 105 | blurEffectView = UIVisualEffectView(effect: blurEffect) 106 | } else { 107 | blurEffectView = UIVisualEffectView(effect: nil) 108 | blurEffectView.backgroundColor = self.backgroundColor 109 | } 110 | 111 | blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 112 | blurEffectView.isUserInteractionEnabled = true 113 | 114 | let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap)) 115 | blurEffectView.addGestureRecognizer(tapGestureRecognizer) 116 | 117 | presentedView?.layer.masksToBounds = true 118 | presentedView?.layer.cornerRadius = 10 119 | 120 | presentedViewController.modalPresentationStyle = .custom 121 | presentedViewController.transitioningDelegate = self 122 | } 123 | 124 | @objc private func handleTap() { 125 | 126 | if !isDisabledTapOutside { 127 | dismiss() 128 | } 129 | } 130 | 131 | override public var frameOfPresentedViewInContainerView: CGRect { 132 | return (sizeDelegate ?? self).frameOfPresentedView(in: containerView?.frame ?? CGRectZero) 133 | } 134 | 135 | override public func dismissalTransitionWillBegin() { 136 | presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] (UIViewControllerTransitionCoordinatorContext) in 137 | self?.blurEffectView.alpha = 0 138 | }, completion: { [weak self] (UIViewControllerTransitionCoordinatorContext) in 139 | self?.blurEffectView.removeFromSuperview() 140 | self?.sizeDelegate?.didDismiss?() 141 | }) 142 | } 143 | 144 | override public func presentationTransitionWillBegin() { 145 | 146 | blurEffectView.alpha = 0 147 | blurEffectView.frame = containerView?.bounds ?? CGRectZero 148 | containerView?.addSubview(blurEffectView) 149 | 150 | presentedView?.frame = frameOfPresentedViewInContainerView 151 | 152 | presentedViewController.transitionCoordinator?.animate(alongsideTransition: { [weak self] (UIViewControllerTransitionCoordinatorContext) in 153 | self?.blurEffectView.alpha = 1 154 | }, completion: { (UIViewControllerTransitionCoordinatorContext) in 155 | 156 | }) 157 | } 158 | 159 | public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 160 | super.viewWillTransition(to: size, with: coordinator) 161 | 162 | coordinator.animate(alongsideTransition: { [weak self] (contx) in 163 | guard let self = self else { return } 164 | self.presentedView?.frame = self.frameOfPresentedViewInContainerView 165 | self.presentedView?.layoutIfNeeded() 166 | }) 167 | } 168 | } 169 | 170 | extension BonsaiController: BonsaiControllerDelegate { 171 | 172 | public func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 173 | return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height/2), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height/2)) 174 | } 175 | 176 | @objc(presentationControllerForPresentedViewController:presentingViewController:sourceViewController:) public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 177 | return self 178 | } 179 | } 180 | 181 | extension BonsaiController: UIViewControllerTransitioningDelegate { 182 | 183 | private func setupTransitioningProperties(transitioning: BonsaiTransitionProperties?) -> UIViewControllerAnimatedTransitioning? { 184 | transitioning?.duration = duration 185 | transitioning?.springWithDamping = springWithDamping 186 | transitioning?.isDisabledDismissAnimation = isDisabledDismissAnimation 187 | return transitioning as? UIViewControllerAnimatedTransitioning 188 | } 189 | 190 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 191 | 192 | if let sizeDelegate = sizeDelegate, sizeDelegate.responds(to:#selector(animationController(forPresented:presenting:source:))) { 193 | return sizeDelegate.animationController?(forPresented: presented, presenting: presenting, source: source) 194 | } 195 | 196 | var transitioning: BonsaiTransitionProperties? 197 | 198 | if let originView = originView { 199 | transitioning = BubbleTransition(originView: originView) 200 | } else { 201 | transitioning = SlideInTransition(fromDirection: fromDirection) 202 | } 203 | 204 | return setupTransitioningProperties(transitioning: transitioning) 205 | } 206 | 207 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 208 | 209 | if let sizeDelegate = sizeDelegate, sizeDelegate.responds(to:#selector(animationController(forDismissed:))) { 210 | return sizeDelegate.animationController?(forDismissed:dismissed) 211 | } 212 | 213 | var transitioning: BonsaiTransitionProperties? 214 | 215 | if let originView = originView { 216 | transitioning = BubbleTransition(originView: originView, reverse: true) 217 | } else { 218 | transitioning = SlideInTransition(fromDirection: dismissDirection ?? fromDirection, reverse: true) 219 | } 220 | 221 | return setupTransitioningProperties(transitioning: transitioning) 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /BonsaiController/Classes/BubbleTransition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BubbleTransition.swift 3 | // BonsaiController 4 | // 5 | // Created by Warif Akhand Rishi on 14/6/18. 6 | // Copyright © 2018 Warif Akhand Rishi. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import AVFoundation 12 | 13 | class BubbleTransition: NSObject, BonsaiTransitionProperties { 14 | 15 | var duration: TimeInterval = 0.3 16 | var springWithDamping: CGFloat = 0.8 17 | var isDisabledDismissAnimation: Bool = false 18 | 19 | private let reverse: Bool 20 | private var originView: UIView! 21 | 22 | var dismissCompletion: (()->Void)? 23 | 24 | init(originView: UIView, reverse: Bool = false) { 25 | self.reverse = reverse 26 | self.originView = originView 27 | } 28 | } 29 | 30 | extension BubbleTransition: UIViewControllerAnimatedTransitioning { 31 | 32 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 33 | return duration 34 | } 35 | 36 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 37 | 38 | let viewControllerKey: UITransitionContextViewControllerKey = reverse ? .from : .to 39 | let viewControllerToAnimate = transitionContext.viewController(forKey: viewControllerKey)! 40 | 41 | let viewToAnimate = viewControllerToAnimate.view! 42 | viewToAnimate.frame = transitionContext.finalFrame(for: viewControllerToAnimate) 43 | 44 | var initialFrame = CGRect.zero 45 | 46 | if let originImageView = originView as? UIImageView, originImageView.contentMode == .scaleAspectFit { 47 | let imageSize = originImageView.image!.size 48 | let imageViewRect = originImageView.frame 49 | let frame = AVMakeRect(aspectRatio:imageSize , insideRect: imageViewRect) 50 | initialFrame = ((originView.superview) ?? originView).convert(frame, to: nil) 51 | } else { 52 | initialFrame = ((originView.superview) ?? originView).convert(originView.frame, to: nil) 53 | } 54 | 55 | let finalFrame = viewToAnimate.frame 56 | 57 | let xScaleFactor = initialFrame.width / finalFrame.width 58 | let yScaleFactor = initialFrame.height / finalFrame.height 59 | 60 | let scaleTransform = CGAffineTransform(scaleX: xScaleFactor, y: yScaleFactor) 61 | 62 | if !reverse { 63 | viewToAnimate.transform = scaleTransform 64 | viewToAnimate.center = CGPoint(x: initialFrame.midX, y: initialFrame.midY) 65 | viewToAnimate.clipsToBounds = true 66 | transitionContext.containerView.addSubview(viewToAnimate) 67 | } 68 | 69 | UIView.animate(withDuration: duration, delay:0.0, usingSpringWithDamping: reverse ? 1 : springWithDamping, initialSpringVelocity: 0.0, animations: { [weak self] in 70 | 71 | guard let self = self else { return } 72 | 73 | if self.reverse && self.isDisabledDismissAnimation { 74 | viewToAnimate.alpha = 0 75 | return 76 | } 77 | 78 | viewToAnimate.transform = self.reverse ? scaleTransform : .identity 79 | 80 | let frame = self.reverse ? initialFrame : finalFrame 81 | viewToAnimate.center = CGPoint(x: frame.midX, y: frame.midY) 82 | 83 | }, completion: { _ in 84 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 85 | }) 86 | 87 | UIView.animate(withDuration: duration/2, delay: duration/2, options: .curveEaseOut, animations: { 88 | viewToAnimate.alpha = self.reverse ? 0.0 : 1 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /BonsaiController/Classes/SlideInTransition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SlideInTransition.swift 3 | // BonsaiController 4 | // 5 | // Created by Warif Akhand Rishi on 9/6/18. 6 | // Copyright © 2018 Warif Akhand Rishi. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @objc 12 | public enum Direction: UInt32 { 13 | 14 | case left, right, top, bottom 15 | 16 | public static func randomDirection() -> Direction { 17 | return Direction(rawValue: arc4random_uniform(4))! 18 | } 19 | } 20 | 21 | class SlideInTransition: NSObject, BonsaiTransitionProperties { 22 | 23 | var duration: TimeInterval = 0.3 24 | var springWithDamping: CGFloat = 0.8 25 | var isDisabledDismissAnimation: Bool = false 26 | 27 | private let reverse: Bool 28 | private let fromDirection: Direction 29 | 30 | init(fromDirection: Direction, reverse: Bool = false) { 31 | self.reverse = reverse 32 | self.fromDirection = fromDirection 33 | } 34 | } 35 | 36 | extension SlideInTransition: UIViewControllerAnimatedTransitioning { 37 | 38 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 39 | 40 | let viewControllerKey: UITransitionContextViewControllerKey = reverse ? .from : .to 41 | let viewControllerToAnimate = transitionContext.viewController(forKey: viewControllerKey)! 42 | 43 | let viewToAnimate = viewControllerToAnimate.view! 44 | viewToAnimate.frame = transitionContext.finalFrame(for: viewControllerToAnimate) 45 | 46 | let offsetFrame = fromDirection.offsetFrameForView(view: viewToAnimate, containerView: transitionContext.containerView) 47 | 48 | if !reverse { 49 | transitionContext.containerView.addSubview(viewToAnimate) 50 | viewToAnimate.frame = offsetFrame 51 | } 52 | 53 | let options: UIView.AnimationOptions = [.curveEaseOut] 54 | 55 | UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: springWithDamping, initialSpringVelocity: 0.0, options: options, animations: { [weak self] in 56 | 57 | guard let self = self else { return } 58 | 59 | if self.reverse && self.isDisabledDismissAnimation { 60 | viewToAnimate.alpha = 0 61 | return 62 | } 63 | 64 | if self.reverse == true { 65 | viewToAnimate.frame = offsetFrame 66 | } else { 67 | viewToAnimate.frame = transitionContext.finalFrame(for: viewControllerToAnimate) 68 | } 69 | }, completion: { _ in 70 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 71 | }) 72 | } 73 | 74 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 75 | return duration 76 | } 77 | } 78 | 79 | private extension Direction { 80 | 81 | func offsetFrameForView(view: UIView, containerView: UIView) -> CGRect { 82 | 83 | var frame = view.frame 84 | 85 | switch self { 86 | case .left: 87 | frame.origin.x = -frame.width 88 | case .right: 89 | frame.origin.x = containerView.bounds.width 90 | case .top: 91 | frame.origin.y = -frame.height 92 | case .bottom: 93 | frame.origin.y = containerView.bounds.height 94 | } 95 | 96 | return frame 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Example/BonsaiController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 11 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 12 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 13 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 14 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 15 | BC03EB7220C14F2D00D1930E /* BonsaiPopupUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC03EB7120C14F2D00D1930E /* BonsaiPopupUtility.swift */; }; 16 | BC160524236F0ABB00D845EB /* BonsaiFullScreenPopUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC160523236F0ABB00D845EB /* BonsaiFullScreenPopUtility.swift */; }; 17 | BC1A1A492178BF6D00063373 /* BonsaiNotificationUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC1A1A482178BF6D00063373 /* BonsaiNotificationUtility.swift */; }; 18 | BC1D2A982163428E00CCD3F3 /* ObjectiveCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1D2A972163428E00CCD3F3 /* ObjectiveCViewController.m */; }; 19 | BC61BCB22116D203006969E0 /* CollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC61BCB12116D203006969E0 /* CollectionViewController.swift */; }; 20 | BC61BCB42116D27C006969E0 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC61BCB32116D27C006969E0 /* CollectionViewCell.swift */; }; 21 | BC74107B20BC40A0008039B3 /* SmallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC74107A20BC409F008039B3 /* SmallViewController.swift */; }; 22 | C0297E313A06FDD815414F20 /* Pods_BonsaiController_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14E6AC5A5F2EF984CB9F04F5 /* Pods_BonsaiController_Example.framework */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 14E6AC5A5F2EF984CB9F04F5 /* Pods_BonsaiController_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BonsaiController_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 50EAA890AD49A70E7FDD7600 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 28 | 607FACD01AFB9204008FA782 /* BonsaiController_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BonsaiController_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 31 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 32 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 34 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 35 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 37 | 6A4C78421957D0D925618EA2 /* Pods-BonsaiController_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BonsaiController_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example.debug.xcconfig"; sourceTree = ""; }; 38 | 74637D70AB4CE6B1B4FA7913 /* Pods-BonsaiController_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BonsaiController_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests.debug.xcconfig"; sourceTree = ""; }; 39 | 8E06610C7E302E5B7833009E /* Pods-BonsaiController_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BonsaiController_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example.release.xcconfig"; sourceTree = ""; }; 40 | B4362DCF45BD8A29FA1528BF /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 41 | BC03EB7120C14F2D00D1930E /* BonsaiPopupUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BonsaiPopupUtility.swift; sourceTree = ""; }; 42 | BC160523236F0ABB00D845EB /* BonsaiFullScreenPopUtility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BonsaiFullScreenPopUtility.swift; sourceTree = ""; }; 43 | BC1A1A482178BF6D00063373 /* BonsaiNotificationUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BonsaiNotificationUtility.swift; sourceTree = ""; }; 44 | BC1D2A952163428D00CCD3F3 /* BonsaiController_Example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BonsaiController_Example-Bridging-Header.h"; sourceTree = ""; }; 45 | BC1D2A962163428E00CCD3F3 /* ObjectiveCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ObjectiveCViewController.h; sourceTree = ""; }; 46 | BC1D2A972163428E00CCD3F3 /* ObjectiveCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ObjectiveCViewController.m; sourceTree = ""; }; 47 | BC61BCB12116D203006969E0 /* CollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewController.swift; sourceTree = ""; }; 48 | BC61BCB32116D27C006969E0 /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; 49 | BC74107A20BC409F008039B3 /* SmallViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmallViewController.swift; sourceTree = ""; }; 50 | C2F172CF86BC86B75EA64ABD /* Pods-BonsaiController_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BonsaiController_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests.release.xcconfig"; sourceTree = ""; }; 51 | DF2D4044E757FF49CEE27814 /* Pods_BonsaiController_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BonsaiController_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | F225CDA1BA1F705E77798746 /* BonsaiController.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = BonsaiController.podspec; path = ../BonsaiController.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | C0297E313A06FDD815414F20 /* Pods_BonsaiController_Example.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 607FACC71AFB9204008FA782 = { 68 | isa = PBXGroup; 69 | children = ( 70 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 71 | 607FACD21AFB9204008FA782 /* Example for BonsaiController */, 72 | 607FACE81AFB9204008FA782 /* Tests */, 73 | 607FACD11AFB9204008FA782 /* Products */, 74 | AB13F431DD2F2E964712EAB1 /* Pods */, 75 | 9BC3825CB39623EDF49A4079 /* Frameworks */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | 607FACD11AFB9204008FA782 /* Products */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 607FACD01AFB9204008FA782 /* BonsaiController_Example.app */, 83 | ); 84 | name = Products; 85 | sourceTree = ""; 86 | }; 87 | 607FACD21AFB9204008FA782 /* Example for BonsaiController */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 91 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 92 | BC74107A20BC409F008039B3 /* SmallViewController.swift */, 93 | BC1A1A462178B2C700063373 /* CollectionView Example */, 94 | BC1A1A452178B0CB00063373 /* Objective-C Example */, 95 | BC1A1A472178B33700063373 /* Utilities */, 96 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 97 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 98 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 99 | 607FACD31AFB9204008FA782 /* Supporting Files */, 100 | BC1D2A952163428D00CCD3F3 /* BonsaiController_Example-Bridging-Header.h */, 101 | ); 102 | name = "Example for BonsaiController"; 103 | path = BonsaiController; 104 | sourceTree = ""; 105 | }; 106 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 607FACD41AFB9204008FA782 /* Info.plist */, 110 | ); 111 | name = "Supporting Files"; 112 | sourceTree = ""; 113 | }; 114 | 607FACE81AFB9204008FA782 /* Tests */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 118 | 607FACE91AFB9204008FA782 /* Supporting Files */, 119 | ); 120 | path = Tests; 121 | sourceTree = ""; 122 | }; 123 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 607FACEA1AFB9204008FA782 /* Info.plist */, 127 | ); 128 | name = "Supporting Files"; 129 | sourceTree = ""; 130 | }; 131 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | F225CDA1BA1F705E77798746 /* BonsaiController.podspec */, 135 | B4362DCF45BD8A29FA1528BF /* README.md */, 136 | 50EAA890AD49A70E7FDD7600 /* LICENSE */, 137 | ); 138 | name = "Podspec Metadata"; 139 | sourceTree = ""; 140 | }; 141 | 9BC3825CB39623EDF49A4079 /* Frameworks */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 14E6AC5A5F2EF984CB9F04F5 /* Pods_BonsaiController_Example.framework */, 145 | DF2D4044E757FF49CEE27814 /* Pods_BonsaiController_Tests.framework */, 146 | ); 147 | name = Frameworks; 148 | sourceTree = ""; 149 | }; 150 | AB13F431DD2F2E964712EAB1 /* Pods */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 6A4C78421957D0D925618EA2 /* Pods-BonsaiController_Example.debug.xcconfig */, 154 | 8E06610C7E302E5B7833009E /* Pods-BonsaiController_Example.release.xcconfig */, 155 | 74637D70AB4CE6B1B4FA7913 /* Pods-BonsaiController_Tests.debug.xcconfig */, 156 | C2F172CF86BC86B75EA64ABD /* Pods-BonsaiController_Tests.release.xcconfig */, 157 | ); 158 | name = Pods; 159 | sourceTree = ""; 160 | }; 161 | BC1A1A452178B0CB00063373 /* Objective-C Example */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | BC1D2A962163428E00CCD3F3 /* ObjectiveCViewController.h */, 165 | BC1D2A972163428E00CCD3F3 /* ObjectiveCViewController.m */, 166 | ); 167 | path = "Objective-C Example"; 168 | sourceTree = ""; 169 | }; 170 | BC1A1A462178B2C700063373 /* CollectionView Example */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | BC61BCB12116D203006969E0 /* CollectionViewController.swift */, 174 | BC61BCB32116D27C006969E0 /* CollectionViewCell.swift */, 175 | ); 176 | path = "CollectionView Example"; 177 | sourceTree = ""; 178 | }; 179 | BC1A1A472178B33700063373 /* Utilities */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | BC03EB7120C14F2D00D1930E /* BonsaiPopupUtility.swift */, 183 | BC1A1A482178BF6D00063373 /* BonsaiNotificationUtility.swift */, 184 | BC160523236F0ABB00D845EB /* BonsaiFullScreenPopUtility.swift */, 185 | ); 186 | path = Utilities; 187 | sourceTree = ""; 188 | }; 189 | /* End PBXGroup section */ 190 | 191 | /* Begin PBXNativeTarget section */ 192 | 607FACCF1AFB9204008FA782 /* BonsaiController_Example */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "BonsaiController_Example" */; 195 | buildPhases = ( 196 | A36F1F0CA65690083F540F28 /* [CP] Check Pods Manifest.lock */, 197 | 607FACCC1AFB9204008FA782 /* Sources */, 198 | 607FACCD1AFB9204008FA782 /* Frameworks */, 199 | 607FACCE1AFB9204008FA782 /* Resources */, 200 | 9B2D23DA1A82265413FF0193 /* [CP] Embed Pods Frameworks */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = BonsaiController_Example; 207 | productName = CustomSizeController; 208 | productReference = 607FACD01AFB9204008FA782 /* BonsaiController_Example.app */; 209 | productType = "com.apple.product-type.application"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | 607FACC81AFB9204008FA782 /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | LastSwiftUpdateCheck = 0830; 218 | LastUpgradeCheck = 1020; 219 | ORGANIZATIONNAME = CocoaPods; 220 | TargetAttributes = { 221 | 607FACCF1AFB9204008FA782 = { 222 | CreatedOnToolsVersion = 6.3.1; 223 | DevelopmentTeam = D5C5TUH7N2; 224 | LastSwiftMigration = 0940; 225 | }; 226 | }; 227 | }; 228 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "BonsaiController" */; 229 | compatibilityVersion = "Xcode 3.2"; 230 | developmentRegion = en; 231 | hasScannedForEncodings = 0; 232 | knownRegions = ( 233 | en, 234 | Base, 235 | ); 236 | mainGroup = 607FACC71AFB9204008FA782; 237 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 238 | projectDirPath = ""; 239 | projectRoot = ""; 240 | targets = ( 241 | 607FACCF1AFB9204008FA782 /* BonsaiController_Example */, 242 | ); 243 | }; 244 | /* End PBXProject section */ 245 | 246 | /* Begin PBXResourcesBuildPhase section */ 247 | 607FACCE1AFB9204008FA782 /* Resources */ = { 248 | isa = PBXResourcesBuildPhase; 249 | buildActionMask = 2147483647; 250 | files = ( 251 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 252 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 253 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXResourcesBuildPhase section */ 258 | 259 | /* Begin PBXShellScriptBuildPhase section */ 260 | 9B2D23DA1A82265413FF0193 /* [CP] Embed Pods Frameworks */ = { 261 | isa = PBXShellScriptBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | ); 265 | inputPaths = ( 266 | "${SRCROOT}/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-frameworks.sh", 267 | "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework", 268 | ); 269 | name = "[CP] Embed Pods Frameworks"; 270 | outputPaths = ( 271 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BonsaiController.framework", 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | shellPath = /bin/sh; 275 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-frameworks.sh\"\n"; 276 | showEnvVarsInLog = 0; 277 | }; 278 | A36F1F0CA65690083F540F28 /* [CP] Check Pods Manifest.lock */ = { 279 | isa = PBXShellScriptBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | ); 283 | inputPaths = ( 284 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 285 | "${PODS_ROOT}/Manifest.lock", 286 | ); 287 | name = "[CP] Check Pods Manifest.lock"; 288 | outputPaths = ( 289 | "$(DERIVED_FILE_DIR)/Pods-BonsaiController_Example-checkManifestLockResult.txt", 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | shellPath = /bin/sh; 293 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 294 | showEnvVarsInLog = 0; 295 | }; 296 | /* End PBXShellScriptBuildPhase section */ 297 | 298 | /* Begin PBXSourcesBuildPhase section */ 299 | 607FACCC1AFB9204008FA782 /* Sources */ = { 300 | isa = PBXSourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | BC74107B20BC40A0008039B3 /* SmallViewController.swift in Sources */, 304 | BC1A1A492178BF6D00063373 /* BonsaiNotificationUtility.swift in Sources */, 305 | BC61BCB42116D27C006969E0 /* CollectionViewCell.swift in Sources */, 306 | BC160524236F0ABB00D845EB /* BonsaiFullScreenPopUtility.swift in Sources */, 307 | BC03EB7220C14F2D00D1930E /* BonsaiPopupUtility.swift in Sources */, 308 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 309 | BC1D2A982163428E00CCD3F3 /* ObjectiveCViewController.m in Sources */, 310 | BC61BCB22116D203006969E0 /* CollectionViewController.swift in Sources */, 311 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | }; 315 | /* End PBXSourcesBuildPhase section */ 316 | 317 | /* Begin PBXVariantGroup section */ 318 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 319 | isa = PBXVariantGroup; 320 | children = ( 321 | 607FACDA1AFB9204008FA782 /* Base */, 322 | ); 323 | name = Main.storyboard; 324 | sourceTree = ""; 325 | }; 326 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 327 | isa = PBXVariantGroup; 328 | children = ( 329 | 607FACDF1AFB9204008FA782 /* Base */, 330 | ); 331 | name = LaunchScreen.xib; 332 | sourceTree = ""; 333 | }; 334 | /* End PBXVariantGroup section */ 335 | 336 | /* Begin XCBuildConfiguration section */ 337 | 607FACED1AFB9204008FA782 /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | ALWAYS_SEARCH_USER_PATHS = NO; 341 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 347 | CLANG_WARN_BOOL_CONVERSION = YES; 348 | CLANG_WARN_COMMA = YES; 349 | CLANG_WARN_CONSTANT_CONVERSION = YES; 350 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 351 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 352 | CLANG_WARN_EMPTY_BODY = YES; 353 | CLANG_WARN_ENUM_CONVERSION = YES; 354 | CLANG_WARN_INFINITE_RECURSION = YES; 355 | CLANG_WARN_INT_CONVERSION = YES; 356 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 357 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 358 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 359 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 360 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 361 | CLANG_WARN_STRICT_PROTOTYPES = YES; 362 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 363 | CLANG_WARN_UNREACHABLE_CODE = YES; 364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 365 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 366 | COPY_PHASE_STRIP = NO; 367 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 368 | ENABLE_STRICT_OBJC_MSGSEND = YES; 369 | ENABLE_TESTABILITY = YES; 370 | GCC_C_LANGUAGE_STANDARD = gnu99; 371 | GCC_DYNAMIC_NO_PIC = NO; 372 | GCC_NO_COMMON_BLOCKS = YES; 373 | GCC_OPTIMIZATION_LEVEL = 0; 374 | GCC_PREPROCESSOR_DEFINITIONS = ( 375 | "DEBUG=1", 376 | "$(inherited)", 377 | ); 378 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 379 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 380 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 381 | GCC_WARN_UNDECLARED_SELECTOR = YES; 382 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 383 | GCC_WARN_UNUSED_FUNCTION = YES; 384 | GCC_WARN_UNUSED_VARIABLE = YES; 385 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 386 | MTL_ENABLE_DEBUG_INFO = YES; 387 | ONLY_ACTIVE_ARCH = YES; 388 | SDKROOT = iphoneos; 389 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 390 | SWIFT_VERSION = 5.0; 391 | }; 392 | name = Debug; 393 | }; 394 | 607FACEE1AFB9204008FA782 /* Release */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | ALWAYS_SEARCH_USER_PATHS = NO; 398 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 400 | CLANG_CXX_LIBRARY = "libc++"; 401 | CLANG_ENABLE_MODULES = YES; 402 | CLANG_ENABLE_OBJC_ARC = YES; 403 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_COMMA = YES; 406 | CLANG_WARN_CONSTANT_CONVERSION = YES; 407 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 408 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 409 | CLANG_WARN_EMPTY_BODY = YES; 410 | CLANG_WARN_ENUM_CONVERSION = YES; 411 | CLANG_WARN_INFINITE_RECURSION = YES; 412 | CLANG_WARN_INT_CONVERSION = YES; 413 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 414 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 415 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 416 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 417 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 418 | CLANG_WARN_STRICT_PROTOTYPES = YES; 419 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 420 | CLANG_WARN_UNREACHABLE_CODE = YES; 421 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 422 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 423 | COPY_PHASE_STRIP = NO; 424 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 425 | ENABLE_NS_ASSERTIONS = NO; 426 | ENABLE_STRICT_OBJC_MSGSEND = YES; 427 | GCC_C_LANGUAGE_STANDARD = gnu99; 428 | GCC_NO_COMMON_BLOCKS = YES; 429 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 430 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 431 | GCC_WARN_UNDECLARED_SELECTOR = YES; 432 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 433 | GCC_WARN_UNUSED_FUNCTION = YES; 434 | GCC_WARN_UNUSED_VARIABLE = YES; 435 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 436 | MTL_ENABLE_DEBUG_INFO = NO; 437 | SDKROOT = iphoneos; 438 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 439 | SWIFT_VERSION = 5.0; 440 | VALIDATE_PRODUCT = YES; 441 | }; 442 | name = Release; 443 | }; 444 | 607FACF01AFB9204008FA782 /* Debug */ = { 445 | isa = XCBuildConfiguration; 446 | baseConfigurationReference = 6A4C78421957D0D925618EA2 /* Pods-BonsaiController_Example.debug.xcconfig */; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | CLANG_ENABLE_MODULES = YES; 450 | DEVELOPMENT_TEAM = D5C5TUH7N2; 451 | INFOPLIST_FILE = "$(SRCROOT)/BonsaiController/Info.plist"; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 453 | MODULE_NAME = ExampleApp; 454 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | SWIFT_OBJC_BRIDGING_HEADER = "BonsaiController/BonsaiController_Example-Bridging-Header.h"; 457 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 458 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 459 | SWIFT_VERSION = 5.0; 460 | TARGETED_DEVICE_FAMILY = "1,2"; 461 | }; 462 | name = Debug; 463 | }; 464 | 607FACF11AFB9204008FA782 /* Release */ = { 465 | isa = XCBuildConfiguration; 466 | baseConfigurationReference = 8E06610C7E302E5B7833009E /* Pods-BonsaiController_Example.release.xcconfig */; 467 | buildSettings = { 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | CLANG_ENABLE_MODULES = YES; 470 | DEVELOPMENT_TEAM = D5C5TUH7N2; 471 | INFOPLIST_FILE = "$(SRCROOT)/BonsaiController/Info.plist"; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 473 | MODULE_NAME = ExampleApp; 474 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 475 | PRODUCT_NAME = "$(TARGET_NAME)"; 476 | SWIFT_OBJC_BRIDGING_HEADER = "BonsaiController/BonsaiController_Example-Bridging-Header.h"; 477 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 478 | SWIFT_VERSION = 5.0; 479 | TARGETED_DEVICE_FAMILY = "1,2"; 480 | }; 481 | name = Release; 482 | }; 483 | /* End XCBuildConfiguration section */ 484 | 485 | /* Begin XCConfigurationList section */ 486 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "BonsaiController" */ = { 487 | isa = XCConfigurationList; 488 | buildConfigurations = ( 489 | 607FACED1AFB9204008FA782 /* Debug */, 490 | 607FACEE1AFB9204008FA782 /* Release */, 491 | ); 492 | defaultConfigurationIsVisible = 0; 493 | defaultConfigurationName = Release; 494 | }; 495 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "BonsaiController_Example" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 607FACF01AFB9204008FA782 /* Debug */, 499 | 607FACF11AFB9204008FA782 /* Release */, 500 | ); 501 | defaultConfigurationIsVisible = 0; 502 | defaultConfigurationName = Release; 503 | }; 504 | /* End XCConfigurationList section */ 505 | }; 506 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 507 | } 508 | -------------------------------------------------------------------------------- /Example/BonsaiController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/BonsaiController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/BonsaiController.xcodeproj/xcshareddata/xcschemes/BonsaiController-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Example/BonsaiController.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/BonsaiController.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/BonsaiController/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BonsaiController 4 | // 5 | // Created by rishi420 on 05/28/2018. 6 | // Copyright (c) 2018 rishi420. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | func applicationWillResignActive(_ application: UIApplication) { 22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 24 | } 25 | 26 | func applicationDidEnterBackground(_ application: UIApplication) { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | func applicationWillEnterForeground(_ application: UIApplication) { 32 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 33 | } 34 | 35 | func applicationDidBecomeActive(_ application: UIApplication) { 36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 37 | } 38 | 39 | func applicationWillTerminate(_ application: UIApplication) { 40 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 41 | } 42 | 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Example/BonsaiController/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Example/BonsaiController/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 36 | 43 | 50 | 51 | 52 | 53 | 60 | 67 | 74 | 81 | 88 | 95 | 102 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 168 | 174 | 180 | 186 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /Example/BonsaiController/BonsaiController_Example-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /Example/BonsaiController/CollectionView Example/CollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewCell.swift 3 | // BonsaiController_Example 4 | // 5 | // Created by Warif Akhand Rishi on 5/8/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CollectionViewCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var aLabel: UILabel! 14 | } 15 | -------------------------------------------------------------------------------- /Example/BonsaiController/CollectionView Example/CollectionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewController.swift 3 | // BonsaiController_Example 4 | // 5 | // Created by Warif Akhand Rishi on 5/8/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import BonsaiController 11 | 12 | class CollectionViewController: UIViewController { 13 | 14 | @IBOutlet weak var aCollectionView: UICollectionView! 15 | 16 | let itemCount = 1000 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | } 22 | } 23 | 24 | // MARK:- From Storyboard 25 | extension CollectionViewController { 26 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 27 | if segue.destination is SmallViewController { 28 | segue.destination.transitioningDelegate = self 29 | segue.destination.modalPresentationStyle = .custom 30 | } 31 | } 32 | } 33 | 34 | // MARK:- CollectionView Data Source 35 | extension CollectionViewController: UICollectionViewDataSource { 36 | 37 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 38 | 39 | return itemCount 40 | } 41 | 42 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 43 | 44 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell 45 | cell.aLabel.text = "\(indexPath.item)" 46 | return cell 47 | } 48 | 49 | } 50 | 51 | // MARK:- CollectionView Delegate (From Code) 52 | //extension CollectionViewController: UICollectionViewDelegate { 53 | // 54 | // func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 55 | // 56 | // let vc = storyboard?.instantiateViewController(withIdentifier: "SmallVC") as! SmallViewController 57 | // vc.view.backgroundColor = .red 58 | // 59 | // vc.transitioningDelegate = self 60 | // vc.modalPresentationStyle = .custom 61 | // present(vc, animated: true, completion: nil) 62 | // } 63 | // 64 | //} 65 | 66 | // MARK:- BonsaiController Delegate 67 | extension CollectionViewController: BonsaiControllerDelegate { 68 | 69 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 70 | 71 | return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height / 4), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height / (4/3))) 72 | } 73 | 74 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 75 | 76 | guard let cell = aCollectionView.cellForItem(at: aCollectionView.indexPathsForSelectedItems!.first!) else { 77 | print("No selected cell") 78 | return nil 79 | } 80 | 81 | var blurEffectStyle = UIBlurEffect.Style.dark 82 | 83 | if #available(iOS 13.0, *) { 84 | blurEffectStyle = .systemChromeMaterial 85 | } 86 | 87 | return BonsaiController(fromView: cell, blurEffectStyle: blurEffectStyle, presentedViewController: presented, delegate: self) 88 | } 89 | } 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | {"images":[{"idiom":"iphone","size":"20x20","scale":"2x","filename":"icon_20@2x.png"},{"idiom":"iphone","size":"20x20","scale":"3x","filename":"icon_20@3x.png"},{"idiom":"iphone","size":"29x29","scale":"2x","filename":"icon_29@2x.png"},{"idiom":"iphone","size":"29x29","scale":"3x","filename":"icon_29@3x.png"},{"idiom":"iphone","size":"40x40","scale":"2x","filename":"icon_40@2x.png"},{"idiom":"iphone","size":"40x40","scale":"3x","filename":"icon_40@3x.png"},{"idiom":"iphone","size":"60x60","scale":"2x","filename":"icon_60@2x.png"},{"idiom":"iphone","size":"60x60","scale":"3x","filename":"icon_60@3x.png"},{"idiom":"ipad","size":"20x20","scale":"1x","filename":"icon_20@1x.png"},{"idiom":"ipad","size":"20x20","scale":"2x","filename":"icon_20@2x.png"},{"idiom":"ipad","size":"29x29","scale":"1x","filename":"icon_29@1x.png"},{"idiom":"ipad","size":"29x29","scale":"2x","filename":"icon_29@2x.png"},{"idiom":"ipad","size":"40x40","scale":"1x","filename":"icon_40@1x.png"},{"idiom":"ipad","size":"40x40","scale":"2x","filename":"icon_40@2x.png"},{"idiom":"ipad","size":"76x76","scale":"1x","filename":"icon_76@1x.png"},{"idiom":"ipad","size":"76x76","scale":"2x","filename":"icon_76@2x.png"},{"idiom":"ipad","size":"83.5x83.5","scale":"2x","filename":"icon_83.5@2x.png"},{"idiom":"ios-marketing","size":"1024x1024","scale":"1x","filename":"icon_1024@1x.png"}],"info":{"version":1,"author":"xcode"}} -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_1024@1x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_20@1x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_20@2x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_20@3x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_29@1x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_29@2x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_29@3x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_40@1x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_40@2x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_40@3x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_60@2x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_60@3x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_76@1x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_76@2x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/AppIcon.appiconset/icon_83.5@2x.png -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Re_Bb@3x.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/bg.imageset/Re_Bb@3x.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/bg.imageset/Re_Bb@3x.pdf -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/leaf.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "leaf@3x.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/BonsaiController/Images.xcassets/leaf.imageset/leaf@3x.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rishi420/Bonsai/5b61a864a7b8a929e5e45ee0195dff88917e10f1/Example/BonsaiController/Images.xcassets/leaf.imageset/leaf@3x.pdf -------------------------------------------------------------------------------- /Example/BonsaiController/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Bonsai 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSPhotoLibraryUsageDescription 28 | to test photo picker example 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | UIInterfaceOrientationPortraitUpsideDown 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Example/BonsaiController/Objective-C Example/ObjectiveCViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ObjectiveCViewController.h 3 | // BonsaiController_Example 4 | // 5 | // Created by Warif Akhand Rishi on 2/10/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ObjectiveCViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/BonsaiController/Objective-C Example/ObjectiveCViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ObjectiveCViewController.m 3 | // BonsaiController_Example 4 | // 5 | // Created by Warif Akhand Rishi on 2/10/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | #import "ObjectiveCViewController.h" 10 | #import "BonsaiController_Example-Swift.h" 11 | 12 | @import BonsaiController; 13 | 14 | @interface ObjectiveCViewController () 15 | 16 | @property (weak, nonatomic) IBOutlet UIButton *exampleButton; 17 | 18 | @end 19 | 20 | @implementation ObjectiveCViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | } 25 | 26 | // MARK:- From Storyboard 27 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 28 | 29 | if ([segue.destinationViewController isKindOfClass:SmallViewController.class]) { 30 | segue.destinationViewController.transitioningDelegate = self; 31 | segue.destinationViewController.modalPresentationStyle = UIModalPresentationCustom; 32 | } 33 | } 34 | 35 | // MARK:- Or From Code 36 | - (IBAction)exampleButtonAction:(id)sender { 37 | 38 | // SmallViewController *smallVC = [self.storyboard instantiateViewControllerWithIdentifier:@"SmallVC"]; 39 | // smallVC.transitioningDelegate = self; 40 | // smallVC.modalPresentationStyle = UIModalPresentationCustom; 41 | // [self presentViewController:smallVC animated:true completion:nil]; 42 | } 43 | 44 | 45 | // MARK:- Bonsai Controller Delegate 46 | - (CGRect)frameOfPresentedViewIn:(CGRect)containerViewFrame { 47 | 48 | return CGRectMake(0, containerViewFrame.size.height / 4, containerViewFrame.size.width, containerViewFrame.size.height / (4.0 / 3.0)); 49 | } 50 | 51 | - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source { 52 | 53 | // Slide animation from .left, .right, .top, .bottom 54 | //return [[BonsaiController alloc] initFromDirection:DirectionBottom blurEffectStyle:UIBlurEffectStyleLight presentedViewController:presented delegate:self]; 55 | 56 | // or Bubble animation initiated from a view 57 | return [[BonsaiController alloc] initFromView:self.exampleButton blurEffectStyle:UIBlurEffectStyleDark presentedViewController:presented delegate:self]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Example/BonsaiController/SmallViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SmallViewController.swift 3 | // BonsaiController 4 | // 5 | // Created by Warif Akhand Rishi on 27/5/18. 6 | // Copyright © 2018 Warif Akhand Rishi. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SmallViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | } 16 | 17 | @IBAction func dismissButtonAction(_ sender: Any) { 18 | dismiss(animated: true, completion: nil) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/BonsaiController/Utilities/BonsaiFullScreenPopUtility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BonsaiFullScreenPopUtility.swift 3 | // PencilTest 4 | // 5 | // Created by Warif Akhand Rishi on 11/4/19. 6 | // Copyright © 2019 Warif Akhand Rishi. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import BonsaiController 11 | 12 | class BonsaiFullScreenPopUtility: NSObject { 13 | 14 | static let shared = BonsaiFullScreenPopUtility() 15 | var sourceView: UIView? 16 | 17 | func show(viewController: UIViewController, fromView: UIView) { 18 | 19 | viewController.transitioningDelegate = self 20 | viewController.modalPresentationStyle = .custom 21 | sourceView = fromView 22 | 23 | topViewController()?.present(viewController, animated: true, completion: nil) 24 | } 25 | } 26 | 27 | private extension BonsaiFullScreenPopUtility { 28 | 29 | func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { 30 | 31 | if let navigationController = controller as? UINavigationController { 32 | return topViewController(controller: navigationController.visibleViewController) 33 | } 34 | 35 | if let tabController = controller as? UITabBarController { 36 | if let selected = tabController.selectedViewController { 37 | return topViewController(controller: selected) 38 | } 39 | } 40 | 41 | if let presented = controller?.presentedViewController { 42 | return topViewController(controller: presented) 43 | } 44 | 45 | return controller 46 | } 47 | } 48 | 49 | extension BonsaiFullScreenPopUtility: BonsaiControllerDelegate { 50 | 51 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 52 | 53 | let bonsaiController = BonsaiController(fromView: sourceView!, blurEffectStyle: .light, presentedViewController: presented, delegate: self) 54 | bonsaiController.presentedView?.layer.cornerRadius = 0 55 | bonsaiController.presentedView?.layer.masksToBounds = false 56 | return bonsaiController 57 | } 58 | 59 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 60 | return containerViewFrame 61 | } 62 | 63 | func didDismiss() { 64 | //NotificationCenter.default.post(name: .refreshScreen, object: nil) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Example/BonsaiController/Utilities/BonsaiNotificationUtility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BonsaiNotificationUtility.swift 3 | // BonsaiController_Example 4 | // 5 | // Created by Warif Akhand Rishi on 18/10/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import BonsaiController 11 | 12 | class BonsaiNotificationUtility: NSObject { 13 | 14 | static let shared = BonsaiNotificationUtility() 15 | let notificationHeight: CGFloat = 120 16 | let notificationDelay: TimeInterval = 2 17 | 18 | func show(viewController: UIViewController) { 19 | 20 | viewController.transitioningDelegate = self 21 | viewController.modalPresentationStyle = .custom 22 | 23 | topViewController()?.present(viewController, animated: true, completion: nil) 24 | } 25 | } 26 | 27 | extension BonsaiNotificationUtility { 28 | 29 | func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { 30 | 31 | if let navigationController = controller as? UINavigationController { 32 | return topViewController(controller: navigationController.visibleViewController) 33 | } 34 | 35 | if let tabController = controller as? UITabBarController { 36 | if let selected = tabController.selectedViewController { 37 | return topViewController(controller: selected) 38 | } 39 | } 40 | 41 | if let presented = controller?.presentedViewController { 42 | return topViewController(controller: presented) 43 | } 44 | 45 | return controller 46 | } 47 | } 48 | 49 | extension BonsaiNotificationUtility: BonsaiControllerDelegate { 50 | 51 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 52 | 53 | let bonsaiController = BonsaiController(fromDirection: .right, blurEffectStyle: .light, presentedViewController: presented, delegate: self) 54 | bonsaiController.perform(#selector(bonsaiController.dismiss), with: nil, afterDelay: notificationDelay) 55 | return bonsaiController 56 | } 57 | 58 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 59 | 60 | return CGRect(origin: .zero, size: CGSize(width: containerViewFrame.width, height: notificationHeight)) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Example/BonsaiController/Utilities/BonsaiPopupUtility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BonsaiPopupUtility.swift 3 | // BonsaiController_Example 4 | // 5 | // Created by Warif Akhand Rishi on 1/6/18. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import BonsaiController 11 | 12 | class BonsaiPopupUtility: NSObject { 13 | 14 | static let shared = BonsaiPopupUtility() 15 | let popupSize = CGSize(width: 280, height: 150) 16 | 17 | func show(viewController: UIViewController) { 18 | 19 | viewController.transitioningDelegate = self 20 | viewController.modalPresentationStyle = .custom 21 | 22 | topViewController()?.present(viewController, animated: true, completion: nil) 23 | } 24 | } 25 | 26 | extension BonsaiPopupUtility { 27 | 28 | func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { 29 | 30 | if let navigationController = controller as? UINavigationController { 31 | return topViewController(controller: navigationController.visibleViewController) 32 | } 33 | 34 | if let tabController = controller as? UITabBarController { 35 | if let selected = tabController.selectedViewController { 36 | return topViewController(controller: selected) 37 | } 38 | } 39 | 40 | if let presented = controller?.presentedViewController { 41 | return topViewController(controller: presented) 42 | } 43 | 44 | return controller 45 | } 46 | } 47 | 48 | extension BonsaiPopupUtility: BonsaiControllerDelegate { 49 | 50 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 51 | 52 | let frame = frameOfPresentedView(in: source.view.frame) 53 | let originFrame = frame.insetBy(dx: -20, dy: -20) 54 | 55 | var blurEffectStyle = UIBlurEffect.Style.light 56 | 57 | if #available(iOS 13.0, *) { 58 | blurEffectStyle = .systemChromeMaterial 59 | } 60 | 61 | let bonsaiController = BonsaiController(fromView: UIView(frame: originFrame), blurEffectStyle: blurEffectStyle, presentedViewController: presented, delegate: self) 62 | bonsaiController.springWithDamping = 0.5 63 | bonsaiController.duration = 0.5 64 | bonsaiController.isDisabledTapOutside = true 65 | bonsaiController.isDisabledDismissAnimation = true 66 | 67 | return bonsaiController 68 | } 69 | 70 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 71 | 72 | return CGRect(origin: CGPoint(x: (containerViewFrame.width - popupSize.width) / 2, y: (containerViewFrame.height - popupSize.height) / 2), size: popupSize) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Example/BonsaiController/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // BonsaiController 4 | // 5 | // Created by Warif Akhand Rishi on 22/5/18. 6 | // Copyright © 2018 Warif Akhand Rishi. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import BonsaiController 11 | import AVKit // Needed for AVPlayerViewController example 12 | 13 | private enum TransitionType { 14 | case none 15 | case bubble 16 | case slide(fromDirection: Direction) 17 | case menu(fromDirection: Direction) 18 | } 19 | 20 | class ViewController: UIViewController { 21 | 22 | @IBOutlet weak var popButton: UIButton! 23 | 24 | private var transitionType: TransitionType = .none 25 | 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | } 29 | 30 | // MARK: Show Small View controller 31 | private func showSmallVC(transition: TransitionType) { 32 | 33 | transitionType = transition 34 | 35 | let vc = storyboard?.instantiateViewController(withIdentifier: "SmallVC") as! SmallViewController 36 | vc.view.backgroundColor = UIColor(red: 208/255.0, green: 5/255.0, blue: 30/255.0, alpha: 1) 37 | vc.transitioningDelegate = self 38 | vc.modalPresentationStyle = .custom 39 | present(vc, animated: true, completion: nil) 40 | } 41 | 42 | // MARK: Storyboard 43 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 44 | print("Prepare Segue") 45 | 46 | if segue.destination is SmallViewController { 47 | transitionType = .slide(fromDirection: .bottom) 48 | segue.destination.transitioningDelegate = self 49 | segue.destination.modalPresentationStyle = .custom 50 | } 51 | } 52 | } 53 | 54 | // MARK:- Button Actions 55 | extension ViewController { 56 | 57 | // MARK: Slide in Buttons 58 | @IBAction func leftButtonAction(_ sender: Any) { 59 | print("Left Button Action") 60 | showSmallVC(transition: .slide(fromDirection: .left)) 61 | } 62 | 63 | @IBAction func rightButtonAction(_ sender: Any) { 64 | print("Right Button Action") 65 | showSmallVC(transition: .slide(fromDirection: .right)) 66 | } 67 | 68 | @IBAction func topButtonAction(_ sender: Any) { 69 | print("Top Button Action") 70 | showSmallVC(transition: .slide(fromDirection: .top)) 71 | } 72 | 73 | @IBAction func bottomButtonAction(_ sender: Any) { 74 | print("Bottom Button Action") 75 | showSmallVC(transition: .slide(fromDirection: .bottom)) 76 | } 77 | 78 | // MARK: Menu Buttons 79 | @IBAction func leftMenuButtonAction(_ sender: Any) { 80 | print("Left Menu Button Action") 81 | showSmallVC(transition: .menu(fromDirection: .left)) 82 | } 83 | 84 | @IBAction func rightMenuButtonAction(_ sender: Any) { 85 | print("Right Menu Button Action") 86 | showSmallVC(transition: .menu(fromDirection: .right)) 87 | } 88 | 89 | // MARK: Popup Button 90 | @IBAction func showAsPopupButtonAction(_ sender: Any) { 91 | print("Popup Button Action") 92 | 93 | let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SmallVC") as! SmallViewController 94 | BonsaiPopupUtility.shared.show(viewController: vc) 95 | } 96 | 97 | // MARK: Notification Button 98 | @IBAction func notificationButtonAction(_ sender: Any) { 99 | print("Notification Button Action") 100 | 101 | let vc = storyboard?.instantiateViewController(withIdentifier: "SmallVC") as! SmallViewController 102 | BonsaiNotificationUtility.shared.show(viewController: vc) 103 | } 104 | 105 | // MARK: Bubble Button 106 | @IBAction func bubbleButtonAction(_ sender: Any) { 107 | print("Bubble Button Action") 108 | showSmallVC(transition: .bubble) 109 | } 110 | 111 | // MARK: Native Buttons 112 | @IBAction func imagePickerButtonAction(_ sender: Any) { 113 | print("Image Picker Button Action") 114 | 115 | guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { 116 | print("Source type not available") 117 | return 118 | } 119 | 120 | transitionType = .slide(fromDirection: Direction.randomDirection()) 121 | 122 | let imagePicker = UIImagePickerController() 123 | imagePicker.sourceType = .photoLibrary; 124 | imagePicker.allowsEditing = true 125 | 126 | imagePicker.transitioningDelegate = self 127 | imagePicker.modalPresentationStyle = .custom 128 | 129 | self.present(imagePicker, animated: true, completion: nil) 130 | } 131 | 132 | @IBAction func fullScreenPopButtonAction(_ sender: UIButton) { 133 | print("Video Player Button Action") 134 | 135 | let vc = storyboard?.instantiateViewController(withIdentifier: "SmallVC") as! SmallViewController 136 | 137 | BonsaiFullScreenPopUtility.shared.show(viewController: vc, fromView: sender) 138 | } 139 | } 140 | 141 | // MARK:- BonsaiController Delegate 142 | extension ViewController: BonsaiControllerDelegate { 143 | 144 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 145 | 146 | var blurEffectStyle = UIBlurEffect.Style.dark 147 | 148 | if #available(iOS 13.0, *) { 149 | blurEffectStyle = .systemChromeMaterial 150 | } 151 | 152 | let backgroundColor = UIColor(white: 0, alpha: 0.5) 153 | 154 | switch transitionType { 155 | case .none: 156 | return nil 157 | 158 | case .bubble: 159 | 160 | // With Blur Style 161 | // return BonsaiController(fromView: popButton, blurEffectStyle: blurEffectStyle, presentedViewController: presented, delegate: self) 162 | 163 | // With Background Color 164 | return BonsaiController(fromView: popButton, backgroundColor: backgroundColor, presentedViewController: presented, delegate: self) 165 | 166 | case .slide(let fromDirection), .menu(let fromDirection): 167 | 168 | // With Blur Style 169 | // return BonsaiController(fromDirection: fromDirection, blurEffectStyle: blurEffectStyle, presentedViewController: presented, delegate: self) 170 | 171 | // With Background Color 172 | return BonsaiController(fromDirection: fromDirection, backgroundColor: backgroundColor, presentedViewController: presented, delegate: self) 173 | } 174 | } 175 | 176 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 177 | 178 | switch transitionType { 179 | case .none: 180 | return CGRect(origin: .zero, size: containerViewFrame.size) 181 | case .slide: 182 | return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height / 4), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height / (4/3))) 183 | case .bubble: 184 | return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height / 4), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height / 2)) 185 | case .menu(let fromDirection): 186 | var origin = CGPoint.zero 187 | if fromDirection == .right { 188 | origin = CGPoint(x: containerViewFrame.width / 2, y: 0) 189 | } 190 | return CGRect(origin: origin, size: CGSize(width: containerViewFrame.width / 2, height: containerViewFrame.height)) 191 | } 192 | } 193 | 194 | func didDismiss() { 195 | print("didDismiss") 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '9.3' 3 | use_frameworks! 4 | 5 | target 'BonsaiController_Example' do 6 | pod 'BonsaiController', :path => '../' 7 | 8 | 9 | target 'BonsaiController_Tests' do 10 | inherit! :search_paths 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BonsaiController (2.0.0) 3 | 4 | DEPENDENCIES: 5 | - BonsaiController (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | BonsaiController: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | BonsaiController: f57b725609942b0f606fb8e8aa058a7eaad9d17a 13 | 14 | PODFILE CHECKSUM: 0f7928e3a84b2cd0384bcf319e842b9fb650eee6 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/BonsaiController.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BonsaiController", 3 | "version": "2.0.0", 4 | "summary": "🌲 Bonsai makes custom frame size and transition animation to any view controller", 5 | "description": "Add the ability to change custom frame size with cool transition animation to any view controller.", 6 | "homepage": "https://github.com/rishi420/Bonsai", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Warif Akhand Rishi": "rishi420@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/rishi420/Bonsai.git", 16 | "tag": "2.0.0" 17 | }, 18 | "swift_version": "4", 19 | "platforms": { 20 | "ios": "9.3" 21 | }, 22 | "source_files": "BonsaiController/Classes/**/*" 23 | } 24 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/CustomSizeController.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BonsaiController", 3 | "version": "1.0.0", 4 | "summary": "Custom size any view controller", 5 | "description": "his CocoaPod adds the ability to change frame of any view controller", 6 | "homepage": "https://github.com/rishi420/CustomSizeController", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Warif Akhand Rishi": "rishi420@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/rishi420/CustomSizeController.git", 16 | "tag": "1.0.0" 17 | }, 18 | "swift_version": "4", 19 | "platforms": { 20 | "ios": "9.3" 21 | }, 22 | "source_files": "CustomSizeController/Classes/**/*" 23 | } 24 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BonsaiController (2.0.0) 3 | 4 | DEPENDENCIES: 5 | - BonsaiController (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | BonsaiController: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | BonsaiController: f57b725609942b0f606fb8e8aa058a7eaad9d17a 13 | 14 | PODFILE CHECKSUM: 0f7928e3a84b2cd0384bcf319e842b9fb650eee6 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/BonsaiController/BonsaiController-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_BonsaiController : NSObject 3 | @end 4 | @implementation PodsDummy_BonsaiController 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/BonsaiController/BonsaiController-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/BonsaiController/BonsaiController-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double BonsaiControllerVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char BonsaiControllerVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/BonsaiController/BonsaiController.modulemap: -------------------------------------------------------------------------------- 1 | framework module BonsaiController { 2 | umbrella header "BonsaiController-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/BonsaiController/BonsaiController.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/BonsaiController/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## BonsaiController 5 | 6 | Copyright (c) 2018 rishi420 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2018 rishi420 <rishi420@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | BonsaiController 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_BonsaiController_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_BonsaiController_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | 145 | if [[ "$CONFIGURATION" == "Debug" ]]; then 146 | install_framework "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework" 147 | fi 148 | if [[ "$CONFIGURATION" == "Release" ]]; then 149 | install_framework "${BUILT_PRODUCTS_DIR}/BonsaiController/BonsaiController.framework" 150 | fi 151 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 152 | wait 153 | fi 154 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_BonsaiController_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_BonsaiController_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_BonsaiController_Example { 2 | umbrella header "Pods-BonsaiController_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Example/Pods-BonsaiController_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "BonsaiController" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_BonsaiController_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_BonsaiController_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 145 | wait 146 | fi 147 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_BonsaiController_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_BonsaiController_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_BonsaiController_Tests { 2 | umbrella header "Pods-BonsaiController_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-BonsaiController_Tests/Pods-BonsaiController_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/BonsaiController/BonsaiController.framework/Headers" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import BonsaiController 3 | 4 | class Tests: XCTestCase { 5 | 6 | override func setUp() { 7 | super.setUp() 8 | // Put setup code here. This method is called before the invocation of each test method in the class. 9 | } 10 | 11 | override func tearDown() { 12 | // Put teardown code here. This method is called after the invocation of each test method in the class. 13 | super.tearDown() 14 | } 15 | 16 | func testExample() { 17 | // This is an example of a functional test case. 18 | XCTAssert(true, "Pass") 19 | } 20 | 21 | func testPerformanceExample() { 22 | // This is an example of a performance test case. 23 | self.measure() { 24 | // Put the code you want to measure the time of here. 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 rishi420 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "BonsaiController", 8 | platforms: [ 9 | .iOS(.v10) 10 | ], 11 | products: [ 12 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 13 | .library( 14 | name: "BonsaiController", 15 | targets: ["BonsaiController"]), 16 | ], 17 | dependencies: [ 18 | // Dependencies declare other packages that this package depends on. 19 | // .package(url: /* package url */, from: "1.0.0"), 20 | ], 21 | targets: [ 22 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 23 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 24 | .target( 25 | name: "BonsaiController", 26 | dependencies: [], 27 | path: "BonsaiController/Classes" 28 | ) 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bonsai 2 | 3 | [![Version](https://img.shields.io/cocoapods/v/BonsaiController.svg?style=flat)](https://cocoapods.org/pods/BonsaiController) 4 | [![License](https://img.shields.io/cocoapods/l/BonsaiController.svg?style=flat)](https://cocoapods.org/pods/BonsaiController) 5 | [![Platform](https://img.shields.io/cocoapods/p/BonsaiController.svg?style=flat)](https://cocoapods.org/pods/BonsaiController) 6 | 7 | 8 | **🌲 Bonsai** makes iOS View Controller present modally in any size and any position with cool transition animation. 9 | 10 | ![Bonsai](https://user-images.githubusercontent.com/2233857/46226655-cbf61d80-c37e-11e8-9d2b-3d69177988a1.png) 11 | 12 | ## Features 13 | 14 | * [x] Makes view controller appear as 15 | - [x] Popup alert (no dismiss on tap outside) 16 | - [x] Notification alert (auto dismiss after delay) 17 | - [x] Side menu (drawer) 18 | * [x] Transition animation 19 | - [x] Slide In from left, right, top and bottom 20 | - [x] Bubble pop from an initial frame or a view 21 | * [x] Blur effect on background 22 | - [x] light, dark, regular, prominent 23 | * [x] Supports Storyboard and Code 24 | * [x] Supports landscape and portrait orientation 25 | * [x] Created with Swift compatible with Objective-C 26 | * [x] Preserves Safe Area and Auto Layout constraints 27 | 28 |

29 | 30 | 31 | 32 |

33 | 34 | 35 | ## Installation with CocoaPods 36 | 37 | BonsaiController is available through [CocoaPods](https://cocoapods.org). To install 38 | it, simply add the following line to your Podfile: 39 | 40 | ```ruby 41 | use_frameworks! 42 | pod 'BonsaiController' 43 | ``` 44 | 45 | ## Install Manually 46 | 47 | Drag the `~/BonsaiController` directory anywhere in your project. 48 | 49 | 50 | ## How to use 51 | 52 | ```Swift 53 | import BonsaiController 54 | ``` 55 | 56 | Add (copy paste) `BonsaiControllerDelegate` extension to your view controller 57 | 58 | ```Swift 59 | extension YourViewController: BonsaiControllerDelegate { 60 | 61 | // return the frame of your Bonsai View Controller 62 | func frameOfPresentedView(in containerViewFrame: CGRect) -> CGRect { 63 | 64 | return CGRect(origin: CGPoint(x: 0, y: containerViewFrame.height / 4), size: CGSize(width: containerViewFrame.width, height: containerViewFrame.height / (4/3))) 65 | } 66 | 67 | // return a Bonsai Controller with SlideIn or Bubble transition animator 68 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { 69 | 70 | /// With Background Color /// 71 | 72 | // Slide animation from .left, .right, .top, .bottom 73 | return BonsaiController(fromDirection: .bottom, backgroundColor: UIColor(white: 0, alpha: 0.5), presentedViewController: presented, delegate: self) 74 | 75 | // or Bubble animation initiated from a view 76 | //return BonsaiController(fromView: yourOriginView, backgroundColor: UIColor(white: 0, alpha: 0.5), presentedViewController: presented, delegate: self) 77 | 78 | 79 | /// With Blur Style /// 80 | 81 | // Slide animation from .left, .right, .top, .bottom 82 | //return BonsaiController(fromDirection: .bottom, blurEffectStyle: .light, presentedViewController: presented, delegate: self) 83 | 84 | // or Bubble animation initiated from a view 85 | //return BonsaiController(fromView: yourOriginView, blurEffectStyle: .dark, presentedViewController: presented, delegate: self) 86 | } 87 | } 88 | ``` 89 | 90 | ## How to present the view controller 91 | 92 | ### From Code: 93 | 94 | ```Swift 95 | let smallVC = YourViewController() // instantiateViewController(withIdentifier:) 96 | smallVC.transitioningDelegate = self 97 | smallVC.modalPresentationStyle = .custom 98 | present(smallVC, animated: true, completion: nil) 99 | ``` 100 | 101 | ### From Storyboard: 102 | 103 | ```Swift 104 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 105 | 106 | if segue.destination is YourViewController { 107 | segue.destination.transitioningDelegate = self 108 | segue.destination.modalPresentationStyle = .custom 109 | } 110 | } 111 | ``` 112 | 113 | 114 | ## Customize 115 | 116 | ### Auto dismiss after delay 117 | 118 | ```Swift 119 | let bonsaiController = BonsaiController(... 120 | bonsaiController.perform(#selector(bonsaiController.dismiss), with: nil, afterDelay: 2) 121 | ``` 122 | 123 | ### Customizable properties (Default values) 124 | 125 | ```Swift 126 | bonsaiController.springWithDamping = 0.8 127 | bonsaiController.duration = 0.4 128 | bonsaiController.isDisabledTapOutside = false 129 | bonsaiController.isDisabledDismissAnimation = false 130 | bonsaiController.dismissDirection = nil // Reverse direction. Availabel only for slide in transition. 131 | ``` 132 | 133 | ### Custom transition animation 134 | 135 | If you want to create your own transition animation, implement this protocol in your viewController 136 | 137 | ```Swift 138 | extension YourViewController: UIViewControllerTransitioningDelegate { 139 | 140 | func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 141 | // Your presentation animation hear 142 | } 143 | 144 | func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 145 | // Your dismiss animation here 146 | } 147 | } 148 | ``` 149 | 150 | ## Usage In Objective-C 151 | 152 | ```objc 153 | #import "YourModuleName-Swift.h" // only if project created in swift 154 | 155 | @import BonsaiController; 156 | ``` 157 | 158 | Add (copy paste) `BonsaiControllerDelegate` extension to your view controller 159 | 160 | ```objc 161 | // MARK:- Bonsai Controller Delegate 162 | - (CGRect)frameOfPresentedViewIn:(CGRect)containerViewFrame { 163 | 164 | return CGRectMake(0, containerViewFrame.size.height / 4, containerViewFrame.size.width, containerViewFrame.size.height / (4.0 / 3.0)); 165 | } 166 | 167 | - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source { 168 | 169 | // Slide animation from .left, .right, .top, .bottom 170 | //return [[BonsaiController alloc] initFromDirection:DirectionBottom blurEffectStyle:UIBlurEffectStyleLight presentedViewController:presented delegate:self]; 171 | 172 | // or Bubble animation initiated from a view 173 | return [[BonsaiController alloc] initFromView:self.exampleButton blurEffectStyle:UIBlurEffectStyleDark presentedViewController:presented delegate:self]; 174 | } 175 | ``` 176 | 177 | ### How to present the view controller(obj-c) 178 | 179 | ### From Code: 180 | 181 | ```objc 182 | SmallViewController *smallVC = [self.storyboard instantiateViewControllerWithIdentifier:@"SmallVC"]; 183 | smallVC.transitioningDelegate = self; 184 | smallVC.modalPresentationStyle = UIModalPresentationCustom; 185 | [self presentViewController:smallVC animated:true completion:nil]; 186 | ``` 187 | 188 | ### From Storyboard: 189 | 190 | ```objc 191 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 192 | 193 | if ([segue.destinationViewController isKindOfClass:SmallViewController.class]) { 194 | segue.destinationViewController.transitioningDelegate = self; 195 | segue.destinationViewController.modalPresentationStyle = UIModalPresentationCustom; 196 | } 197 | } 198 | ``` 199 | 200 | 201 | ## Example 202 | 203 | An example project is included with this repo. To run the example project, clone the repo, and run `pod install` from the Example directory first. 204 | 205 | 206 | ## Minimum Requirements 207 | 208 | * Xcode 10.2 with swift5 (check previous releases and pod versions for older xcode) 209 | * iOS 9.3 210 | 211 | 212 | ## Your input is welcome! 213 | 214 | If you have any suggestions, please get in touch with us.
215 | If you need help or found a bug, please open an issue.
216 | If you have a new transition animation or want to contribute, please submit a pull request. 217 | 218 | 219 | ## Let us know! 220 | 221 | If you like BonsaiController, give it a ★ at the top right of this page.
222 | Using BonsaiController in your app? Send us a link to your app in the app store! 223 | 224 | 225 | ## Credits 226 | 227 | - Jelly - https://github.com/SebastianBoldt/Jelly 228 | - PresentHalfModal - https://github.com/khuong291/PresentHalfModal 229 | - SideMenu - https://github.com/jonkykong/SideMenu 230 | - TransitionTreasury - https://github.com/DianQK/TransitionTreasury 231 | - Transition - https://github.com/Touchwonders/Transition 232 | - StarWars.iOS - https://github.com/Yalantis/StarWars.iOS 233 | - Hero - https://github.com/HeroTransitions/Hero 234 | 235 | 236 | ## Thank You 237 | 238 | A special thank you to everyone that has contributed to this library to make it better. Your support is appreciated! 239 | 240 | 241 | ## Author 242 | 243 | Developer: Warif Akhand Rishi, rishi420@gmail.com
244 | Designer: Takmila Tasmim Mim, mim.tasmim93@gmail.com 245 | 246 | 247 | ## License 248 | 249 | BonsaiController is available under the MIT license. See the LICENSE file for more info. 250 | 251 | 252 | 253 | ## Support Us 254 | 255 | Buy Me A Coffee 256 | 257 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-tactile --------------------------------------------------------------------------------