diff --git a/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj b/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj index cc4da9461..891f5fdc8 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj +++ b/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj @@ -85,6 +85,7 @@ 8F0B81122670200300463726 /* AppCenterDistribute in Frameworks */ = {isa = PBXBuildFile; platformFilter = ios; productRef = 8F0B81112670200300463726 /* AppCenterDistribute */; }; 8F0B8114267021A700463726 /* AppCenterAnalytics in Frameworks */ = {isa = PBXBuildFile; platformFilter = ios; productRef = 8F0B8113267021A700463726 /* AppCenterAnalytics */; }; 8F0B8116267021A700463726 /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; platformFilter = ios; productRef = 8F0B8115267021A700463726 /* AppCenterCrashes */; }; + 9211BC612BD97B7900B95200 /* DemoHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9211BC602BD97B7900B95200 /* DemoHostingController.swift */; }; 92279B352B97F5DA00994D88 /* ButtonDemoController_SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92279B342B97F5D900994D88 /* ButtonDemoController_SwiftUI.swift */; }; 923DF2DB271158C900637646 /* libFluentUI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 923DF2DA271158C900637646 /* libFluentUI.a */; }; 923DF2DF27115B4700637646 /* FluentUIResources-ios.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 923DF2DC271158CD00637646 /* FluentUIResources-ios.bundle */; }; @@ -221,6 +222,7 @@ 807E8B4428F9F8B8002B8F84 /* PillButtonDemoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillButtonDemoController.swift; sourceTree = ""; }; 80AECC0B2630F1BB005AF2F3 /* BottomCommandingDemoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomCommandingDemoController.swift; sourceTree = ""; }; 80B1F7002628D8BB004DFEE5 /* BottomSheetDemoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomSheetDemoController.swift; sourceTree = ""; }; + 9211BC602BD97B7900B95200 /* DemoHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoHostingController.swift; sourceTree = ""; }; 92279B342B97F5D900994D88 /* ButtonDemoController_SwiftUI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonDemoController_SwiftUI.swift; sourceTree = ""; }; 923DF2DA271158C900637646 /* libFluentUI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libFluentUI.a; sourceTree = BUILT_PRODUCTS_DIR; }; 923DF2DC271158CD00637646 /* FluentUIResources-ios.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = "FluentUIResources-ios.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -457,6 +459,7 @@ 92DD1E8C279F496300FDEE0F /* DemoAppearanceView.swift */, E6842995247C350700A29C40 /* DemoColorThemes.swift */, A5DCA75F211E3B4C005F4CB7 /* DemoController.swift */, + 9211BC602BD97B7900B95200 /* DemoHostingController.swift */, A5CEC21120E436F10016922A /* DemoListViewController.swift */, 92561E722718AD090072ED00 /* DemoTableViewController.swift */, 6FC8AD3A28DBAF280010C0F8 /* ReadmeViewController.swift */, @@ -818,6 +821,7 @@ 6FEED93B28A6E5520099D178 /* AliasColorTokensDemoController.swift in Sources */, A5DCA760211E3B4C005F4CB7 /* DemoController.swift in Sources */, F30B74382A7DB177000F63A0 /* ListActionItemDemoController_SwiftUI.swift in Sources */, + 9211BC612BD97B7900B95200 /* DemoHostingController.swift in Sources */, 5328D97B26FBA3EA00F3723B /* IndeterminateProgressBarDemoController.swift in Sources */, 5373D55F2694C3070032A3B4 /* AvatarDemoController.swift in Sources */, 7D0931C124AAA3D30072458A /* SideTabBarDemoController.swift in Sources */, diff --git a/ios/FluentUI.Demo/FluentUI.Demo/DemoController.swift b/ios/FluentUI.Demo/FluentUI.Demo/DemoController.swift index 40dd820ab..93062846b 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/DemoController.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/DemoController.swift @@ -166,7 +166,7 @@ class DemoController: UIViewController { let readmeButton = UIBarButtonItem(image: UIImage(systemName: "info.circle.fill"), style: .plain, target: self, - action: #selector(showReadmePopover)) + action: #selector(showReadmePopover(_:))) navigationItem.rightBarButtonItems = [readmeButton, settingsButton] } diff --git a/ios/FluentUI.Demo/FluentUI.Demo/DemoHostingController.swift b/ios/FluentUI.Demo/FluentUI.Demo/DemoHostingController.swift new file mode 100644 index 000000000..91a16c4df --- /dev/null +++ b/ios/FluentUI.Demo/FluentUI.Demo/DemoHostingController.swift @@ -0,0 +1,75 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// + +import SwiftUI +import FluentUI + +/// A specialized subclass of `FluentThemedHostingController` that can be used for SwiftUI demo screens. +class DemoHostingController: FluentThemedHostingController { + init(rootView: AnyView, title: String, readmeText: String? = nil) { + super.init(rootView: rootView) + self.title = title + } + + @objc required dynamic init?(coder aDecoder: NSCoder) { + preconditionFailure("init(coder:) has not been implemented") + } + + @MainActor required dynamic init(rootView: AnyView) { + super.init(rootView: rootView) + } + + override func viewDidLoad() { + super.viewDidLoad() + configureAppearanceAndReadmePopovers() + } + + // MARK: - Demo Appearance Popover + + func configureAppearanceAndReadmePopovers() { + let settingsButton = UIBarButtonItem(image: UIImage(named: "ic_fluent_settings_24_regular"), + style: .plain, + target: self, + action: #selector(showAppearancePopover(_:))) + let readmeButton = UIBarButtonItem(image: UIImage(systemName: "info.circle.fill"), + style: .plain, + target: self, + action: #selector(showReadmePopover(_:))) + navigationItem.rightBarButtonItems = [readmeButton, settingsButton] + } + + @objc func showReadmePopover(_ sender: UIBarButtonItem) { + readmeViewController.popoverPresentationController?.barButtonItem = sender + readmeViewController.popoverPresentationController?.delegate = self + self.present(readmeViewController, animated: true, completion: nil) + } + + @objc func showAppearancePopover(_ sender: AnyObject, presenter: UIViewController) { + if let barButtonItem = sender as? UIBarButtonItem { + appearanceController.popoverPresentationController?.barButtonItem = barButtonItem + } else if let sourceView = sender as? UIView { + appearanceController.popoverPresentationController?.sourceView = sourceView + appearanceController.popoverPresentationController?.sourceRect = sourceView.bounds + } + appearanceController.popoverPresentationController?.delegate = self + presenter.present(appearanceController, animated: true, completion: nil) + } + + @objc func showAppearancePopover(_ sender: AnyObject) { + showAppearancePopover(sender, presenter: self) + } + + private var readmeText: String? + + private lazy var appearanceController: DemoAppearanceController = .init(delegate: self as? DemoAppearanceDelegate) + private lazy var readmeViewController: ReadmeViewController = .init(readmeString: readmeText) +} + +extension DemoHostingController: UIPopoverPresentationControllerDelegate { + /// Overridden to allow for popover-style modal presentation on compact (e.g. iPhone) devices. + func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { + return .none + } +} diff --git a/ios/FluentUI.Demo/FluentUI.Demo/DemoTableViewController.swift b/ios/FluentUI.Demo/FluentUI.Demo/DemoTableViewController.swift index 02551fd6f..40adc96bd 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/DemoTableViewController.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/DemoTableViewController.swift @@ -57,7 +57,7 @@ class DemoTableViewController: UITableViewController { let readmeButton = UIBarButtonItem(image: UIImage(systemName: "info.circle.fill"), style: .plain, target: self, - action: #selector(showReadmePopover)) + action: #selector(showReadmePopover(_:))) navigationItem.rightBarButtonItems = [readmeButton, settingsButton] } diff --git a/ios/FluentUI.Demo/FluentUI.Demo/Demos/ButtonDemoController_SwiftUI.swift b/ios/FluentUI.Demo/FluentUI.Demo/Demos/ButtonDemoController_SwiftUI.swift index 97ee8ee7e..c1f4a9204 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/Demos/ButtonDemoController_SwiftUI.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/Demos/ButtonDemoController_SwiftUI.swift @@ -7,58 +7,17 @@ import FluentUI import SwiftUI import UIKit -class ButtonDemoControllerSwiftUI: FluentThemedHostingController { - @objc required dynamic init?(coder aDecoder: NSCoder) { - preconditionFailure("init(coder:) has not been implemented") - } - +class ButtonDemoControllerSwiftUI: DemoHostingController { init() { - super.init(rootView: AnyView(ButtonDemoView())) - self.title = "Button (SwiftUI)" + super.init(rootView: AnyView(ButtonDemoView()), title: "Button (SwiftUI)") } - @MainActor required dynamic init(rootView: AnyView) { - super.init(rootView: rootView) - } - - override func viewDidLoad() { - super.viewDidLoad() - configureAppearanceAndReadmePopovers() - } - - // MARK: - Demo Appearance Popover - - func configureAppearanceAndReadmePopovers() { - let settingsButton = UIBarButtonItem(image: UIImage(named: "ic_fluent_settings_24_regular"), - style: .plain, - target: self, - action: #selector(showAppearancePopover(_:))) - navigationItem.rightBarButtonItems = [settingsButton] - } - - @objc func showAppearancePopover(_ sender: AnyObject, presenter: UIViewController) { - if let barButtonItem = sender as? UIBarButtonItem { - appearanceController.popoverPresentationController?.barButtonItem = barButtonItem - } else if let sourceView = sender as? UIView { - appearanceController.popoverPresentationController?.sourceView = sourceView - appearanceController.popoverPresentationController?.sourceRect = sourceView.bounds - } - appearanceController.popoverPresentationController?.delegate = self - presenter.present(appearanceController, animated: true, completion: nil) - } - - @objc func showAppearancePopover(_ sender: AnyObject) { - showAppearancePopover(sender, presenter: self) + @objc required dynamic init?(coder aDecoder: NSCoder) { + preconditionFailure("init(coder:) has not been implemented") } - private lazy var appearanceController: DemoAppearanceController = .init(delegate: self as? DemoAppearanceDelegate) - -} - -extension ButtonDemoControllerSwiftUI: UIPopoverPresentationControllerDelegate { - /// Overridden to allow for popover-style modal presentation on compact (e.g. iPhone) devices. - func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { - return .none + @MainActor required dynamic init(rootView: AnyView) { + preconditionFailure("init(rootView:) has not been implemented") } }