Skip to content

Commit

Permalink
Adding SwiftUI Drawer controller (#344)
Browse files Browse the repository at this point in the history
SwiftUI implementation of DrawerController, includes drawer across horizontal axis
  • Loading branch information
kubalani committed Jan 6, 2021
1 parent eef904b commit 8de8d54
Show file tree
Hide file tree
Showing 12 changed files with 1,329 additions and 3 deletions.
4 changes: 4 additions & 0 deletions ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
114CF8B82423E10900D064AA /* ColorDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114CF8B72423E10900D064AA /* ColorDemoController.swift */; };
22EABB182509A80B00C4BE72 /* IndeterminateProgressBarDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22EABB172509A80B00C4BE72 /* IndeterminateProgressBarDemoController.swift */; };
3F8A30ED25801F89003743A9 /* DrawerVnextDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F8A30EC25801F89003743A9 /* DrawerVnextDemoController.swift */; };
497DC2DE24185896008D86F8 /* PillButtonBarDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 497DC2DD24185896008D86F8 /* PillButtonBarDemoController.swift */; };
53B659B8257AA44F00070405 /* ButtonVnextDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53B659B7257AA44F00070405 /* ButtonVnextDemoController.swift */; };
53B659C4257AA69E00070405 /* DrawerDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5DCA75D211E3A92005F4CB7 /* DrawerDemoController.swift */; };
Expand Down Expand Up @@ -78,6 +79,7 @@
114CF8B72423E10900D064AA /* ColorDemoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorDemoController.swift; sourceTree = "<group>"; };
22EABB172509A80B00C4BE72 /* IndeterminateProgressBarDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndeterminateProgressBarDemoController.swift; sourceTree = "<group>"; };
3D3224A9AADF58C324059464 /* Pods-FluentUI.Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FluentUI.Demo.release.xcconfig"; path = "Target Support Files/Pods-FluentUI.Demo/Pods-FluentUI.Demo.release.xcconfig"; sourceTree = "<group>"; };
3F8A30EC25801F89003743A9 /* DrawerVnextDemoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DrawerVnextDemoController.swift; sourceTree = "<group>"; };
497DC2DD24185896008D86F8 /* PillButtonBarDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PillButtonBarDemoController.swift; sourceTree = "<group>"; };
53B659B7257AA44F00070405 /* ButtonVnextDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonVnextDemoController.swift; sourceTree = "<group>"; };
53EA0FA1257ED8AF00899357 /* AvatarVnextDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarVnextDemoController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -300,6 +302,7 @@
D0F59E3224F4E3A700358DC2 /* PassThroughDrawerDemoController.swift */,
CCC18C2E2501C75F00BE830E /* CardViewDemoController.swift */,
EC8EA6AF2580D82A00F191CE /* ListVnextDemoController.swift */,
3F8A30EC25801F89003743A9 /* DrawerVnextDemoController.swift */
);
path = Demos;
sourceTree = "<group>";
Expand Down Expand Up @@ -507,6 +510,7 @@
E6842996247C350700A29C40 /* DemoColorThemeWindows.swift in Sources */,
53F7385F257760B60043071D /* ObjectiveCDemoController.m in Sources */,
A5CEC21020E436F10016922A /* AppDelegate.swift in Sources */,
3F8A30ED25801F89003743A9 /* DrawerVnextDemoController.swift in Sources */,
B4414794228F6FDF0040E88E /* OtherCellsSampleData.swift in Sources */,
53F73862257803DE0043071D /* HUDDemoController.swift in Sources */,
53B659B8257AA44F00070405 /* ButtonVnextDemoController.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions ios/FluentUI.Demo/FluentUI.Demo/Demos.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ let demos: [(title: String, controllerClass: UIViewController.Type)] = [
("ContactCollectionView", ContactCollectionViewDemoController.self),
("DateTimePicker", DateTimePickerDemoController.self),
("DrawerController", DrawerDemoController.self),
("DrawerController (Vnext)", DrawerVnextDemoController.self),
("HUD", HUDDemoController.self),
("IndeterminateProgressBar", IndeterminateProgressBarDemoController.self),
("Label", LabelDemoController.self),
Expand Down
165 changes: 165 additions & 0 deletions ios/FluentUI.Demo/FluentUI.Demo/Demos/DrawerVnextDemoController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//

import FluentUI
import UIKit
import SwiftUI

// MARK: DrawerContentController

class DrawerContentController: DemoController {

public func actionViews() -> [UIView] {
let spacer = UIView()
spacer.backgroundColor = .orange
spacer.layer.borderWidth = 1
spacer.heightAnchor.constraint(greaterThanOrEqualToConstant: 20).isActive = true

var views = [UIView]()
views.append(createButton(title: "Dismiss", action: { [weak self ] _ in
if let strongSelf = self {
strongSelf.dismissButtonTapped()
}
}).view)
views.append(createButton(title: "Dismiss (no animation)", action: { [weak self ] _ in
if let strongSelf = self {
strongSelf.dismissNotAnimatedButtonTapped()
}
}).view)
views.append(spacer)
return views
}

public func containerForActionViews() -> UIView {
let container = DemoController.createVerticalContainer()
for view in actionViews() {
container.addArrangedSubview(view)
}
addBackgroundColor(container, color: Colors.surfacePrimary)
return container
}

private func addBackgroundColor(_ stackview: UIStackView, color: UIColor) {
let subView = UIView(frame: stackview.bounds)
subView.backgroundColor = color
subView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
stackview.insertSubview(subView, at: 0)
}

@objc private func dismissButtonTapped() {
dismiss(animated: true)
}

@objc private func dismissNotAnimatedButtonTapped() {
dismiss(animated: false)
}

override func viewDidLoad() {
super.viewDidLoad()
view = containerForActionViews()
}
}

class DrawerVnextDemoController: DemoController, DrawerVnextControllerDelegate {

private var drawerController: DrawerVnext?

override func viewDidLoad() {
super.viewDidLoad()

addTitle(text: "Left/Right Drawer")
addRow(items: [
createButton(title: "Show from leading with clear background", action: { [weak self ] _ in
if let strongSelf = self {
strongSelf.showLeftDrawerClearBackgroundButtonTapped()
}
}).view,
createButton(title: "Show from trailing with clear background", action: { [weak self ] _ in
if let strongSelf = self {
strongSelf.showRightDrawerClearBackgroundButtonTapped()
}
}).view
],
itemSpacing: Constants.verticalSpacing,
stretchItems: true)
addRow(items: [
createButton(title: "Show from leading with dimmed background", action: { [weak self ] _ in
if let strongSelf = self {
strongSelf.showLeftDrawerDimmedBackgroundButtonTapped()
}
}).view,
createButton(title: "Show from trailing with dimmed background", action: { [weak self ] _ in
if let strongSelf = self {
strongSelf.showRightDrawerDimmedBackgroundButtonTapped()
}
}).view
],
itemSpacing: Constants.verticalSpacing,
stretchItems: true)
addDescription(text: "Swipe from the left or right edge of the screen to reveal a drawer interactively")

container.addArrangedSubview(UIView())

// Screen edge gestures to interactively present side drawers

let isLeadingEdgeLeftToRight = view.effectiveUserInterfaceLayoutDirection == .leftToRight

let leadingEdgeGesture = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handleScreenEdgePan))
leadingEdgeGesture.edges = isLeadingEdgeLeftToRight ? .left : .right
view.addGestureRecognizer(leadingEdgeGesture)
navigationController?.navigationController?.interactivePopGestureRecognizer?.require(toFail: leadingEdgeGesture)

let trailingEdgeGesture = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handleScreenEdgePan))
trailingEdgeGesture.edges = isLeadingEdgeLeftToRight ? .right : .left
view.addGestureRecognizer(trailingEdgeGesture)

drawerController = DrawerVnext(contentViewController: DrawerContentController())
drawerController?.delegate = self
}

@objc private func showLeftDrawerClearBackgroundButtonTapped() {
if let drawerController = drawerController {
drawerController.state.backgroundDimmed = false
drawerController.state.presentationDirection = .left
present(drawerController, animated: true, completion: nil)
}
}

@objc private func showLeftDrawerDimmedBackgroundButtonTapped() {
if let drawerController = drawerController {
drawerController.state.backgroundDimmed = true
drawerController.state.presentationDirection = .left
present(drawerController, animated: true, completion: nil)
}
}

@objc private func showRightDrawerClearBackgroundButtonTapped() {
if let drawerController = drawerController {
drawerController.state.backgroundDimmed = false
drawerController.state.presentationDirection = .right
present(drawerController, animated: true, completion: nil)
}
}

@objc private func showRightDrawerDimmedBackgroundButtonTapped() {
if let drawerController = drawerController {
drawerController.state.backgroundDimmed = true
drawerController.state.presentationDirection = .right
present(drawerController, animated: true, completion: nil)
}
}

@objc private func handleScreenEdgePan(gesture: UIScreenEdgePanGestureRecognizer) {
guard gesture.state == .began else {
return
}

if view.effectiveUserInterfaceLayoutDirection == .leftToRight {
self.showRightDrawerDimmedBackgroundButtonTapped()
} else {
self.showLeftDrawerClearBackgroundButtonTapped()
}
}
}
24 changes: 24 additions & 0 deletions ios/FluentUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
22010B752523CEB700FF1F10 /* ActivityViewAnimating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22010B6F2523CB2D00FF1F10 /* ActivityViewAnimating.swift */; };
22EABB1A2509AAD100C4BE72 /* IndeterminateProgressBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22EABB192509AAD100C4BE72 /* IndeterminateProgressBarView.swift */; };
22EABB1B250A196200C4BE72 /* IndeterminateProgressBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22EABB192509AAD100C4BE72 /* IndeterminateProgressBarView.swift */; };
3F11A47A2587F97500D3BEBC /* Drawer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F11A4792587F97500D3BEBC /* Drawer.swift */; };
3F800525259AE20C004DDB8B /* Drawer+UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F800524259AE20C004DDB8B /* Drawer+UIKit.swift */; };
3F800547259D5D6D004DDB8B /* SlideOverPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F800546259D5D6D004DDB8B /* SlideOverPanel.swift */; };
3F800564259DA182004DDB8B /* SideOverPanel+Modifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F800563259DA182004DDB8B /* SideOverPanel+Modifiers.swift */; };
497DC2D924185885008D86F8 /* PillButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 497DC2D724185885008D86F8 /* PillButtonBar.swift */; };
497DC2DA24185885008D86F8 /* PillButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 497DC2D724185885008D86F8 /* PillButtonBar.swift */; };
497DC2DB24185885008D86F8 /* PillButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 497DC2D824185885008D86F8 /* PillButton.swift */; };
Expand Down Expand Up @@ -316,6 +320,10 @@
118D9847230BBA2300BC0B72 /* TabBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItem.swift; sourceTree = "<group>"; };
22010B6F2523CB2D00FF1F10 /* ActivityViewAnimating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityViewAnimating.swift; sourceTree = "<group>"; };
22EABB192509AAD100C4BE72 /* IndeterminateProgressBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndeterminateProgressBarView.swift; sourceTree = "<group>"; };
3F11A4792587F97500D3BEBC /* Drawer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Drawer.swift; sourceTree = "<group>"; };
3F800524259AE20C004DDB8B /* Drawer+UIKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Drawer+UIKit.swift"; sourceTree = "<group>"; };
3F800546259D5D6D004DDB8B /* SlideOverPanel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SlideOverPanel.swift; sourceTree = "<group>"; };
3F800563259DA182004DDB8B /* SideOverPanel+Modifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SideOverPanel+Modifiers.swift"; sourceTree = "<group>"; };
497DC2D724185885008D86F8 /* PillButtonBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PillButtonBar.swift; sourceTree = "<group>"; };
497DC2D824185885008D86F8 /* PillButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PillButton.swift; sourceTree = "<group>"; };
537315B225438B15001FD14C /* iOS13_4_compatibility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = iOS13_4_compatibility.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -567,6 +575,17 @@
path = "Tab Bar";
sourceTree = "<group>";
};
3F11A4782587F97500D3BEBC /* DrawerVnext */ = {
isa = PBXGroup;
children = (
3F11A4792587F97500D3BEBC /* Drawer.swift */,
3F800546259D5D6D004DDB8B /* SlideOverPanel.swift */,
3F800563259DA182004DDB8B /* SideOverPanel+Modifiers.swift */,
3F800524259AE20C004DDB8B /* Drawer+UIKit.swift */,
);
path = DrawerVnext;
sourceTree = "<group>";
};
497DC2D62418585D008D86F8 /* Pill Button Bar */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -680,6 +699,7 @@
A5CEC15320D980B20016922A /* FluentUI */ = {
isa = PBXGroup;
children = (
3F11A4782587F97500D3BEBC /* DrawerVnext */,
CCC18C2A2501B1A900BE830E /* Card */,
B4F118EA21C8270F00855942 /* Badge Field */,
FDFB8AE921361C860046850A /* Calendar */,
Expand Down Expand Up @@ -1389,7 +1409,9 @@
FD41C8BE22DD47120086F899 /* UINavigationItem+Navigation.swift in Sources */,
7DC2FB2D24D209E800367A55 /* Presence.swift in Sources */,
B4E782C12176AD5E00A7DFCE /* ActionsCell.swift in Sources */,
3F11A47A2587F97500D3BEBC /* Drawer.swift in Sources */,
FD56FD962192754B0023C7EA /* DateTimePickerViewComponent.swift in Sources */,
3F800547259D5D6D004DDB8B /* SlideOverPanel.swift in Sources */,
FDFB8AF021361C9D0046850A /* CalendarViewDayTodayCell.swift in Sources */,
FD41C88422DD13230086F899 /* ContentScrollViewTraits.swift in Sources */,
FD97580F2191118E00B67319 /* DateTimePickerViewComponentCell.swift in Sources */,
Expand Down Expand Up @@ -1428,6 +1450,7 @@
0BCEFADE2485FEC00088CEE5 /* PopupMenuProtocols.swift in Sources */,
A578C4A22321CFD6002D5C40 /* Avatar.swift in Sources */,
B444D6B62183A9740002B4D4 /* BadgeView.swift in Sources */,
3F800525259AE20C004DDB8B /* Drawer+UIKit.swift in Sources */,
FD7254E72146E946002F4069 /* CalendarViewDayCell.swift in Sources */,
A589F854211BA03200471C23 /* Label.swift in Sources */,
A56CE7B622E68A7800AA77EE /* UIColor+Extensions.swift in Sources */,
Expand Down Expand Up @@ -1465,6 +1488,7 @@
C0A0D76F233AEF6C00F432FD /* ShimmerLinesViewAppearance.swift in Sources */,
FD256C5B2183B90B00EC9588 /* DatePickerSelectionManager.swift in Sources */,
A5CEC23120E451D00016922A /* Button.swift in Sources */,
3F800564259DA182004DDB8B /* SideOverPanel+Modifiers.swift in Sources */,
FDF41EDB2141A23B00EC527C /* UIViewController+Extensions.swift in Sources */,
FD56FD95219131430023C7EA /* DateTimePickerView.swift in Sources */,
FDA1AF8C21484625001AE720 /* BlurringView.swift in Sources */,
Expand Down
1 change: 0 additions & 1 deletion ios/FluentUI/Drawer/DrawerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ open class DrawerController: UIViewController {
updateContainerViewBottomConstraint()
}
}

private var containerViewCenterObservation: NSKeyValueObservation?

private var useCustomBackgroundColor: Bool = false
Expand Down

0 comments on commit 8de8d54

Please sign in to comment.