Skip to content

Commit

Permalink
Add convenience methods for presenting BottomSheet
Browse files Browse the repository at this point in the history
  • Loading branch information
mikhailmaslo committed Aug 15, 2022
1 parent 9e58dcd commit 88e5a21
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 28 deletions.
12 changes: 12 additions & 0 deletions BottomSheetDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
7DB24C8A27BD1813001030C7 /* BottomSheetUtils.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7DB24C8327BD1813001030C7 /* BottomSheetUtils.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
7DB24C9327BD18F1001030C7 /* BottomSheetUtils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7DB24C8327BD1813001030C7 /* BottomSheetUtils.framework */; };
7DB24CEC27BD1FAD001030C7 /* JMMulticastDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DB24CE927BD1FAD001030C7 /* JMMulticastDelegate.m */; };
7DD5185028AA2FBA003F3D2A /* UIViewController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DD5184E28AA2F46003F3D2A /* UIViewController+Convenience.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -109,6 +110,7 @@
7DA9B01927439FA100284B0F /* UIControl+EventHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIControl+EventHandling.swift"; sourceTree = "<group>"; };
7DB24C8327BD1813001030C7 /* BottomSheetUtils.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BottomSheetUtils.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7DB24CE927BD1FAD001030C7 /* JMMulticastDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JMMulticastDelegate.m; sourceTree = "<group>"; };
7DD5184E28AA2F46003F3D2A /* UIViewController+Convenience.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Convenience.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -243,6 +245,7 @@
isa = PBXGroup;
children = (
7DA6E0B4274F915A009F5C37 /* BottomSheetTransitioningDelegate.swift */,
7DD5184D28AA2F3B003F3D2A /* Extensions */,
7DA6E0B5274F915A009F5C37 /* NavigationController */,
7DA6E0B9274F915A009F5C37 /* Presentation */,
);
Expand Down Expand Up @@ -329,6 +332,14 @@
path = Sources/BottomSheetUtils;
sourceTree = "<group>";
};
7DD5184D28AA2F3B003F3D2A /* Extensions */ = {
isa = PBXGroup;
children = (
7DD5184E28AA2F46003F3D2A /* UIViewController+Convenience.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
7DDA237727BD25C800D006FE /* include */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -499,6 +510,7 @@
7DA6E0E7274F919A009F5C37 /* UIScrollView+MulticastDelegate.swift in Sources */,
7DA6E0E8274F919A009F5C37 /* UINavigationController+MulticastDelegate.swift in Sources */,
7DA6E0E6274F9196009F5C37 /* CGSize+Helpers.swift in Sources */,
7DD5185028AA2FBA003F3D2A /* UIViewController+Convenience.swift in Sources */,
7DA6E0E2274F9196009F5C37 /* UIViewController+Lifecycle.swift in Sources */,
7DA6E0DC274F918A009F5C37 /* BottomSheetNavigationStyle.swift in Sources */,
7DA6E0DA274F918A009F5C37 /* BottomSheetNavigationController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,37 +48,10 @@ final class RootViewController: UIViewController {
}
}

private var transitionDelegate: UIViewControllerTransitioningDelegate?

@objc
private func handleShowBottomSheet() {
let viewController = ResizeViewController(initialHeight: 300)
let navigationController = BottomSheetNavigationController(rootViewController: viewController)
transitionDelegate = BottomSheetTransitioningDelegate(presentationControllerFactory: self)
navigationController.transitioningDelegate = transitionDelegate
navigationController.modalPresentationStyle = .custom
present(navigationController, animated: true, completion: nil)
}
}

extension RootViewController: BottomSheetPresentationControllerFactory {
func makeBottomSheetPresentationController(
presentedViewController: UIViewController,
presentingViewController: UIViewController?
) -> BottomSheetPresentationController {
.init(
presentedViewController: presentedViewController,
presentingViewController: presentingViewController,
dismissalHandler: self
)
}
}

extension RootViewController: BottomSheetModalDismissalHandler {
var canBeDismissed: Bool { true }

func performDismissal(animated: Bool) {
presentedViewController?.dismiss(animated: animated, completion: nil)
transitionDelegate = nil
presentBottomSheet(viewController: navigationController)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//
// UIViewController+Convenience.swift
// BottomSheetDemo
//
// Created by Mikhail Maslo on 15.08.2022.
// Copyright © 2022 Joom. All rights reserved.
//

import UIKit

public final class DefaultBottomSheetPresentationControllerFactory: BottomSheetPresentationControllerFactory {
// MARK: - Nested types

public typealias DismissalHandlerProvider = () -> BottomSheetModalDismissalHandler

// MARK: - Public properties

private let dismissalHandlerProvider: DismissalHandlerProvider

// MARK: - Init

public init(dismissalHandlerProvider: @escaping DismissalHandlerProvider) {
self.dismissalHandlerProvider = dismissalHandlerProvider
}

// MARK: - BottomSheetPresentationControllerFactory

public func makeBottomSheetPresentationController(
presentedViewController: UIViewController,
presentingViewController: UIViewController?
) -> BottomSheetPresentationController {
BottomSheetPresentationController(
presentedViewController: presentedViewController,
presentingViewController: presentingViewController,
dismissalHandler: dismissalHandlerProvider()
)
}
}

public final class DefaultBottomSheetModalDismissalHandler: BottomSheetModalDismissalHandler {
// MARK: - Private properties

private weak var presentingViewController: UIViewController?
private let dismissCompletion: (() -> Void)?

// MARK: - Init

init(
presentingViewController: UIViewController?,
dismissCompletion: (() -> Void)?
) {
self.presentingViewController = presentingViewController
self.dismissCompletion = dismissCompletion
}

// MARK: - BottomSheetModalDismissalHandler

public let canBeDismissed: Bool = true

public func performDismissal(animated: Bool) {
presentingViewController?.presentedViewController?.dismiss(animated: animated, completion: dismissCompletion)
}
}

public extension UIViewController {
private(set) var bottomSheetTransitionDelegate: UIViewControllerTransitioningDelegate? {
get { objc_getAssociatedObject(self, &Self.bottomSheetTransitionDelegateKey) as? UIViewControllerTransitioningDelegate }
set { objc_setAssociatedObject(self, &Self.bottomSheetTransitionDelegateKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
}

private static var bottomSheetTransitionDelegateKey: UInt8 = 0

func presentBottomSheet(viewController: UIViewController) {
weak var presentingViewController = self
weak var currentBottomSheetTransitionDelegate: UIViewControllerTransitioningDelegate?
let presentationControllerFactory = DefaultBottomSheetPresentationControllerFactory {
DefaultBottomSheetModalDismissalHandler(presentingViewController: presentingViewController) {
if currentBottomSheetTransitionDelegate === presentingViewController?.bottomSheetTransitionDelegate {
presentingViewController?.bottomSheetTransitionDelegate = nil
}
}
}
bottomSheetTransitionDelegate = BottomSheetTransitioningDelegate(
presentationControllerFactory: presentationControllerFactory
)
currentBottomSheetTransitionDelegate = bottomSheetTransitionDelegate
viewController.transitioningDelegate = bottomSheetTransitionDelegate
viewController.modalPresentationStyle = .custom
present(viewController, animated: true, completion: nil)
}
}

0 comments on commit 88e5a21

Please sign in to comment.