Skip to content

Commit

Permalink
Napriyad/drawer max expansion height (microsoft#264)
Browse files Browse the repository at this point in the history
* Changes in Drawer controller to specify an optional maximum expansion height

* Renamed variable

* Restricting expansion animation till preferredMaximumExpansionHeight

* Moved Presentation cap logic to DrawerPresentationController

* Formatted using swiftlint

* Changed access level of the preferredMaximumExpansionHeight. Provided through initilizers now

* revomed screenBound global const

* Some cleanup

* Refactored if-else block

* removed unwanted changes, restructured some code

* Fixing a bad commit

* Added a check, that got removed by mistake
  • Loading branch information
npriyadarshi authored Oct 23, 2020
1 parent caef8e6 commit b12f4d5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
21 changes: 15 additions & 6 deletions ios/FluentUI.Demo/FluentUI.Demo/Demos/DrawerDemoController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class DrawerDemoController: DemoController {

addTitle(text: "Top Drawer")
container.addArrangedSubview(createButton(title: "Show resizable", action: #selector(showTopDrawerButtonTapped)))
container.addArrangedSubview(createButton(title: "Show resizable with max content height", action: #selector(showTopDrawerWithMaxContentHeightTapped)))
container.addArrangedSubview(createButton(title: "Show non dismissable", action: #selector(showTopDrawerNotDismissableButtonTapped)))
container.addArrangedSubview(createButton(title: "Show changing resizing behaviour", action: #selector(showTopDrawerChangingResizingBehaviour)))
container.addArrangedSubview(createButton(title: "Show with no animation", action: #selector(showTopDrawerNotAnimatedButtonTapped)))
Expand All @@ -38,6 +39,7 @@ class DrawerDemoController: DemoController {

addTitle(text: "Bottom Drawer")
container.addArrangedSubview(createButton(title: "Show resizable", action: #selector(showBottomDrawerButtonTapped)))
container.addArrangedSubview(createButton(title: "Show resizable with max content height", action: #selector(showBottomDrawerWithMaxContentHeightTapped)))
container.addArrangedSubview(createButton(title: "Show with underlying interactable content view", action: #selector(showBottomDrawerWithUnderlyingInteractableViewButtonTapped)))
container.addArrangedSubview(createButton(title: "Show changing resizing behaviour", action: #selector(showBottomDrawerChangingResizingBehaviour)))
container.addArrangedSubview(createButton(title: "Show with no animation", action: #selector(showBottomDrawerNotAnimatedButtonTapped)))
Expand Down Expand Up @@ -79,13 +81,14 @@ class DrawerDemoController: DemoController {
adjustHeightForKeyboard: Bool = false,
animated: Bool = true,
customWidth: Bool = false,
respectSafeAreaWidth: Bool = false) -> DrawerController {
respectSafeAreaWidth: Bool = false,
maxDrawerHeight: CGFloat = -1) -> DrawerController {
let controller: DrawerController
if let sourceView = sourceView {
controller = DrawerController(sourceView: sourceView, sourceRect: sourceView.bounds.insetBy(dx: sourceView.bounds.width / 2, dy: 0), presentationOrigin: presentationOrigin, presentationDirection: presentationDirection)
controller = DrawerController(sourceView: sourceView, sourceRect: sourceView.bounds.insetBy(dx: sourceView.bounds.width / 2, dy: 0), presentationOrigin: presentationOrigin, presentationDirection: presentationDirection, preferredMaximumHeight: maxDrawerHeight)
controller.delegate = self
} else if let barButtonItem = barButtonItem {
controller = DrawerController(barButtonItem: barButtonItem, presentationOrigin: presentationOrigin, presentationDirection: presentationDirection)
controller = DrawerController(barButtonItem: barButtonItem, presentationOrigin: presentationOrigin, presentationDirection: presentationDirection, preferredMaximumHeight: maxDrawerHeight)
} else {
preconditionFailure("Presenting a drawer requires either a sourceView or a barButtonItem")
}
Expand Down Expand Up @@ -152,10 +155,14 @@ class DrawerDemoController: DemoController {
presentDrawer(sourceView: sender, presentationDirection: .down, contentView: containerForActionViews(), resizingBehavior: .dismissOrExpand)
}

@objc private func showTopDrawerWithMaxContentHeightTapped(sender: UIButton) {
presentDrawer(sourceView: sender, presentationDirection: .down, contentView: containerForActionViews(drawerHasFlexibleHeight: false), resizingBehavior: .expand, maxDrawerHeight: 350)
}

@objc private func showTopDrawerNotDismissableButtonTapped(sender: UIButton) {
presentDrawer(sourceView: sender, presentationDirection: .down, contentView: containerForActionViews(), resizingBehavior: .expand)
}

@objc private func showTopDrawerChangingResizingBehaviour(sender: UIButton) {
presentDrawer(sourceView: sender, presentationDirection: .down, contentView: containerForActionViews(drawerHasFlexibleHeight: true, drawerHasToggleResizingBehaviorButton: true), resizingBehavior: .expand)
}
Expand Down Expand Up @@ -185,6 +192,10 @@ class DrawerDemoController: DemoController {
presentDrawer(sourceView: sender, presentationDirection: .up, contentView: containerForActionViews(), resizingBehavior: .dismissOrExpand)
}

@objc private func showBottomDrawerWithMaxContentHeightTapped(sender: UIButton) {
presentDrawer(sourceView: sender, presentationDirection: .up, contentView: containerForActionViews(drawerHasFlexibleHeight: false), resizingBehavior: .dismissOrExpand, maxDrawerHeight: 350)
}

@objc private func showBottomDrawerChangingResizingBehaviour(sender: UIButton) {
presentDrawer(sourceView: sender, presentationDirection: .up, contentView: containerForActionViews(drawerHasFlexibleHeight: true, drawerHasToggleResizingBehaviorButton: true), resizingBehavior: .expand)
}
Expand Down Expand Up @@ -302,13 +313,11 @@ class DrawerDemoController: DemoController {
@objc private func dismissNotAnimatedButtonTapped() {
dismiss(animated: false)
}

@objc private func updateResizingBehaviourButtonTapped(sender: UIButton) {
guard let drawer = presentedViewController as? DrawerController else {
return
}
let isResizingBehaviourNone = drawer.resizingBehavior == .none

drawer.resizingBehavior = isResizingBehaviourNone ? .expand : .none
sender.setTitle(isResizingBehaviourNone ? "Resizing - None" : "Resizing - Expand", for: .normal)
}
Expand Down
30 changes: 22 additions & 8 deletions ios/FluentUI/Drawer/DrawerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ open class DrawerController: UIViewController {
}
}
}

@objc open var presentationBackground: DrawerPresentationBackground = .black

/// Use `passThroughView` to make underlying view interactable. This view can be set from presenting view controller to recieve all the touch events from drawer's presentation background.
Expand Down Expand Up @@ -253,7 +254,7 @@ open class DrawerController: UIViewController {
if presentationDirection.isHorizontal && resizingBehavior == .dismissOrExpand {
resizingBehavior = .dismiss
}

// If the drawer is already loaded, update the resizing handle when resizing behaviour is changed.
if isViewLoaded {
updateResizingHandleView()
Expand Down Expand Up @@ -408,6 +409,7 @@ open class DrawerController: UIViewController {
private var useCustomBackgroundColor: Bool = false
/// for iPad split mode, navigation bar has a different dark elevated color, and if it is a `.down` presentation style, match `Colors.NavigationBar.background` elevated color
private var useNavigationBarBackgroundColor: Bool = false
private let preferredMaximumExpansionHeight: CGFloat

/**
Initializes `DrawerController` to be presented as a popover from `sourceRect` in `sourceView` on iPad and as a slideover on iPhone/iPad.
Expand All @@ -416,13 +418,15 @@ open class DrawerController: UIViewController {
- Parameter sourceRect: The rectangle in the specified view in which to anchor the popover.
- Parameter presentationOrigin: The offset (in screen coordinates) from which to show a slideover. If not provided it will be calculated automatically: bottom of navigation bar for `.down` presentation and edge of the screen for other presentations.
- Parameter presentationDirection: The direction of slideover presentation.
- Parameter preferredMaximumHeight: The maximum height to which the drawer is preferred to expand
*/
@objc public init(sourceView: UIView, sourceRect: CGRect, presentationOrigin: CGFloat = -1, presentationDirection: DrawerPresentationDirection) {
@objc public init(sourceView: UIView, sourceRect: CGRect, presentationOrigin: CGFloat = -1, presentationDirection: DrawerPresentationDirection, preferredMaximumHeight: CGFloat = -1) {
self.sourceView = sourceView
self.sourceRect = sourceRect
self.barButtonItem = nil
self.presentationOrigin = presentationOrigin == -1 ? nil : presentationOrigin
self.presentationDirection = presentationDirection
self.preferredMaximumExpansionHeight = preferredMaximumHeight

super.init(nibName: nil, bundle: nil)

Expand All @@ -436,12 +440,13 @@ open class DrawerController: UIViewController {
- Parameter presentationOrigin: The offset (in screen coordinates) from which to show a slideover. If not provided it will be calculated automatically: bottom of navigation bar for `.down` presentation and edge of the screen for other presentations.
- Parameter presentationDirection: The direction of slideover presentation.
*/
@objc public init(barButtonItem: UIBarButtonItem, presentationOrigin: CGFloat = -1, presentationDirection: DrawerPresentationDirection) {
@objc public init(barButtonItem: UIBarButtonItem, presentationOrigin: CGFloat = -1, presentationDirection: DrawerPresentationDirection, preferredMaximumHeight: CGFloat = -1) {
self.sourceView = nil
self.sourceRect = nil
self.barButtonItem = barButtonItem
self.presentationOrigin = presentationOrigin == -1 ? nil : presentationOrigin
self.presentationDirection = presentationDirection
self.preferredMaximumExpansionHeight = preferredMaximumHeight

super.init(nibName: nil, bundle: nil)

Expand Down Expand Up @@ -495,7 +500,7 @@ open class DrawerController: UIViewController {

open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// Configure the resizing handle view according to resizing behaviour and disable the gesture recogniser(if any) till view actually appears
updateResizingHandleView()
resizingGestureRecognizer?.isEnabled = false
Expand Down Expand Up @@ -598,7 +603,15 @@ open class DrawerController: UIViewController {
private func updatePreferredContentSize(isExpanded: Bool) {
isPreferredContentSizeBeingChangedInternally = true
if isExpanded {
preferredContentSize.height = UIScreen.main.bounds.height
let screenHeight: CGFloat = UIScreen.main.bounds.height
if preferredMaximumExpansionHeight != -1 &&
preferredMaximumExpansionHeight < screenHeight &&
preferredMaximumExpansionHeight >= originalDrawerHeight {
// Preferred max expansion size is in range [originalDrawerHeight, screenHeight)
preferredContentSize.height = preferredMaximumExpansionHeight
} else {
preferredContentSize.height = screenHeight
}
} else {
preferredContentSize.height = normalPreferredContentHeight
}
Expand Down Expand Up @@ -667,7 +680,7 @@ open class DrawerController: UIViewController {
initResizingHandleView()
if presentationDirection == .down {
containerView.addArrangedSubview(newView)

// Force layout the containerView to avoid unwanted animation of view addition.
containerView.layoutIfNeeded()
} else {
Expand Down Expand Up @@ -710,7 +723,7 @@ open class DrawerController: UIViewController {
}
updateResizingHandleViewAccessibility()
}

private func updateResizingHandleView() {
if canResize {
if showsResizingHandle {
Expand Down Expand Up @@ -966,7 +979,8 @@ extension DrawerController: UIViewControllerTransitioningDelegate {
shouldUseWindowFullWidthInLandscape: shouldUseWindowFullWidthInLandscape,
shouldRespectSafeAreaForWindowFullWidth: shouldRespectSafeAreaForWindowFullWidth,
passThroughView: passThroughView,
shadowOffset: shadowOffset)
shadowOffset: shadowOffset,
maximumPresentationHeight: preferredMaximumExpansionHeight)
drawerPresentationController.drawerPresentationControllerDelegate = self
return drawerPresentationController
case .popover:
Expand Down
9 changes: 7 additions & 2 deletions ios/FluentUI/Drawer/DrawerPresentationController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class DrawerPresentationController: UIPresentationController {

public weak var drawerPresentationControllerDelegate: DrawerPresentationControllerDelegate?

private let preferredMaximumPresentationSize: CGFloat

init(presentedViewController: UIViewController,
presentingViewController: UIViewController?,
source: UIViewController,
Expand All @@ -47,7 +49,8 @@ class DrawerPresentationController: UIPresentationController {
shouldUseWindowFullWidthInLandscape: Bool,
shouldRespectSafeAreaForWindowFullWidth: Bool,
passThroughView: UIView?,
shadowOffset: CGFloat) {
shadowOffset: CGFloat,
maximumPresentationHeight: CGFloat) {
sourceViewController = source
self.sourceObject = sourceObject
self.presentationOrigin = presentationOrigin
Expand All @@ -58,6 +61,7 @@ class DrawerPresentationController: UIPresentationController {
self.shouldRespectSafeAreaForWindowFullWidth = shouldRespectSafeAreaForWindowFullWidth
self.passThroughView = passThroughView
self.shadowOffset = shadowOffset
self.preferredMaximumPresentationSize = maximumPresentationHeight

super.init(presentedViewController: presentedViewController, presenting: presentingViewController)

Expand Down Expand Up @@ -376,7 +380,8 @@ class DrawerPresentationController: UIPresentationController {
}
contentSize.height = min(contentSize.height, contentFrame.height)
if extraContentSize >= 0 || extraContentSizeEffectWhenCollapsing == .resize {
contentSize.height = min(contentSize.height + extraContentSize, contentFrame.height)
let maxContentSize = preferredMaximumPresentationSize != -1 ? preferredMaximumPresentationSize : contentFrame.height
contentSize.height = min(contentSize.height + extraContentSize, maxContentSize)
}

contentFrame.origin.x += (contentFrame.width - contentSize.width) / 2
Expand Down

0 comments on commit b12f4d5

Please sign in to comment.