From 7babfaac62551383fd1767035962acf1afb198e6 Mon Sep 17 00:00:00 2001 From: Mike Schreiber Date: Fri, 7 Jun 2024 08:43:15 -0700 Subject: [PATCH 1/3] Remove iOS 15 support --- MicrosoftFluentUI.podspec | 2 +- .../FluentUI.Demo.xcodeproj/project.pbxproj | 6 +- ...iasColorTokensDemoController_SwiftUI.swift | 17 +---- ios/FluentUI/Core/ControlHostingView.swift | 2 +- .../Core/FluentThemedHostingController.swift | 72 +------------------ ios/FluentUI/List/FluentList.swift | 3 + ios/FluentUI/Pill Button Bar/PillButton.swift | 1 - ios/xcode/FluentUI_common.xcconfig | 2 +- 8 files changed, 11 insertions(+), 94 deletions(-) diff --git a/MicrosoftFluentUI.podspec b/MicrosoftFluentUI.podspec index 36a8a3c137..61e4f87d8f 100644 --- a/MicrosoftFluentUI.podspec +++ b/MicrosoftFluentUI.podspec @@ -12,7 +12,7 @@ Pod::Spec.new do |s| # iOS - s.ios.deployment_target = "15.0" + s.ios.deployment_target = "16.0" s.subspec 'Avatar_ios' do |avatar_ios| avatar_ios.platform = :ios diff --git a/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj b/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj index 38f23ca314..b5a4c35988 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj +++ b/ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj @@ -1087,7 +1087,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DOGFOOD; @@ -1187,7 +1187,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1247,7 +1247,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift b/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift index 595a5c9941..f27670d9a6 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift @@ -25,21 +25,7 @@ struct AliasColorTokensDemoView: View { @Environment(\.fluentTheme) var fluentTheme: FluentTheme var body: some View { - if #available(iOS 16.0, *) { - formContent.scrollContentBackground(.hidden) - } else { - formContent.onAppear { - UITableView.appearance().backgroundColor = .clear - } - .onDisappear { - UITableView.appearance().backgroundColor = .systemGroupedBackground - } - } - } - - @ViewBuilder - var formContent: some View { - Form { + FluentList { ForEach(AliasColorTokensDemoSection.allCases, id: \.self) { demoSection in // No need for SwiftUI section in SwiftUI demo! if demoSection != .swiftUI { @@ -47,7 +33,6 @@ struct AliasColorTokensDemoView: View { } } } - .background(fluentTheme.swiftUIColor(.backgroundCanvas)) } @ViewBuilder diff --git a/ios/FluentUI/Core/ControlHostingView.swift b/ios/FluentUI/Core/ControlHostingView.swift index 294bbe4e4c..13e7ee6af8 100644 --- a/ios/FluentUI/Core/ControlHostingView.swift +++ b/ios/FluentUI/Core/ControlHostingView.swift @@ -37,7 +37,7 @@ open class ControlHostingView: UIView { /// - Parameter controlView: An `AnyView`-wrapped component to host. public init(_ controlView: AnyView) { hostingController = FluentThemedHostingController.init(rootView: controlView) - hostingController.disableSafeAreaInsets() + hostingController.sizingOptions = [.intrinsicContentSize] super.init(frame: .zero) self.configureHostedView() diff --git a/ios/FluentUI/Core/FluentThemedHostingController.swift b/ios/FluentUI/Core/FluentThemedHostingController.swift index a1571461ac..230be7cffe 100644 --- a/ios/FluentUI/Core/FluentThemedHostingController.swift +++ b/ios/FluentUI/Core/FluentThemedHostingController.swift @@ -6,41 +6,8 @@ import UIKit import SwiftUI -extension UIView { - - /// Associated keys created for the added UIView stored properties. - struct AssociatedKeys { - static var shouldUseZeroEdgeInsets: UInt8 = 0 - } - - /// Adds a stored property to the UIView that defines whether the UIView should return UIEdgeInsets.zero from its safeAreaInsets property. - /// This property is intended to be used by the UIHostingView class, which is a private subclass of UIView in the SwiftUI Framework. - var shouldUseZeroEdgeInsets: Bool { - get { - return objc_getAssociatedObject(self, &AssociatedKeys.shouldUseZeroEdgeInsets) as? Bool ?? false - } - set { - objc_setAssociatedObject(self, &AssociatedKeys.shouldUseZeroEdgeInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - } - - /// Computed property that will be swizzled with UIView.safeAreaInsets by exchange of implementations. - /// This swizzling is meant to be used in UIHostingView instances which are private in the SwiftUI framework. - /// Do not call this property getter directly. - @objc var customSafeAreaInsets: UIEdgeInsets { - if shouldUseZeroEdgeInsets { - return .zero - } - - // Because this property will be swizzled with UIView.safeAreaInsets by exchanging - // implementations, this call makes sure to call it by this property's name which - // will contain the original implementation of UIView.safeAreaInsets. - return self.customSafeAreaInsets - } -} - /// FluentUI specific implementation of the UIHostingController. This is primarily useful for adding `FluentTheme` observation -/// to any wrapped Fluent controls. Additionally, this class adds a workaround for disabling safeAreaInsets for its view on iOS 15. +/// to any wrapped Fluent controls. open class FluentThemedHostingController: UIHostingController { @MainActor required dynamic public override init(rootView: AnyView) { @@ -68,13 +35,6 @@ open class FluentThemedHostingController: UIHostingController { } } - /// iOS 15.0 fix for UIHostingController that does not automatically resize to hug subviews - open override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - - view.setNeedsUpdateConstraints() - } - // MARK: - Theme management @objc private func themeDidChange(_ notification: Notification) { @@ -101,33 +61,3 @@ open class FluentThemedHostingController: UIHostingController { private var controlView: AnyView } - -// MARK: - Safe Area Inset swizzling - -extension FluentThemedHostingController { - /// Static constant that will be guaranteed to have its initialization executed only once during the lifetime of the application. - private static let swizzleSafeAreaInsetsOnce: Void = { - // A FluentUIHostingController instance needs to be created so that the class type for the private UIHostingViewwe can be retrived. - let hostingControllerViewClass: AnyClass = FluentThemedHostingController(rootView: AnyView(EmptyView())).view.classForCoder - - guard let originalMethod = class_getInstanceMethod(hostingControllerViewClass, #selector(getter: UIView.safeAreaInsets)), - let swizzledMethod = class_getInstanceMethod(hostingControllerViewClass, #selector(getter: UIView.customSafeAreaInsets)) else { - preconditionFailure("UIHostingController zeroSafeAreaInsets swizzling failed.") - } - - method_exchangeImplementations(originalMethod, swizzledMethod) - }() - - /// Disables the UIHostingController's view safe area insets by swizzling the UIView.safeAreaInsets property and returning UIEdgeInsets.zero if the UIView.shouldUseZeroEdgeInsets is true. - /// This is a known issue and it's currently tracked by Radar bug FB8176223 - https://openradar.appspot.com/FB8176223 - func disableSafeAreaInsets() { - // We no longer need the workarounds from `FluentUIHostingController` in - // iOS 16, but we still need it for 14 and 15. - if #unavailable(iOS 16) { - view.shouldUseZeroEdgeInsets = true - _ = FluentThemedHostingController.swizzleSafeAreaInsetsOnce - } else { - sizingOptions = [.intrinsicContentSize] - } - } -} diff --git a/ios/FluentUI/List/FluentList.swift b/ios/FluentUI/List/FluentList.swift index 0b4d8fbe1b..05fa9c2ebd 100644 --- a/ios/FluentUI/List/FluentList.swift +++ b/ios/FluentUI/List/FluentList.swift @@ -44,12 +44,14 @@ public struct FluentList: View { case .insetGrouped: list .listStyle(.insetGrouped) + .scrollContentBackground(.hidden) // TODO: Directly use `FluentList` token set instead of `ListItem` .background(ListItem.listBackgroundColor(for: .grouped)) .listStyling_iOS17() case .plain: list .listStyle(.plain) + .scrollContentBackground(.hidden) // TODO: Directly use `FluentList` token set instead of `ListItem` .background(ListItem.listBackgroundColor(for: .plain)) } @@ -66,6 +68,7 @@ public struct FluentList: View { /// Content to render inside the list private var content: () -> ListContent + @Environment(\.fluentTheme) private var fluentTheme: FluentTheme } // MARK: - Environment diff --git a/ios/FluentUI/Pill Button Bar/PillButton.swift b/ios/FluentUI/Pill Button Bar/PillButton.swift index 58bb113506..afbd8dc672 100644 --- a/ios/FluentUI/Pill Button Bar/PillButton.swift +++ b/ios/FluentUI/Pill Button Bar/PillButton.swift @@ -176,7 +176,6 @@ open class PillButton: UIButton, TokenizedControlInternal { updateAttributedTitle() } - @available(iOS 15, *) private func updateAttributedTitle() { let itemTitle = pillBarItem.title var attributedTitle = AttributedString(itemTitle) diff --git a/ios/xcode/FluentUI_common.xcconfig b/ios/xcode/FluentUI_common.xcconfig index 9ab0929fd3..ce5b744bc5 100644 --- a/ios/xcode/FluentUI_common.xcconfig +++ b/ios/xcode/FluentUI_common.xcconfig @@ -46,7 +46,7 @@ GCC_WARN_UNDECLARED_SELECTOR = YES GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE GCC_WARN_UNUSED_FUNCTION = YES GCC_WARN_UNUSED_VARIABLE = YES -IPHONEOS_DEPLOYMENT_TARGET = 15.0 +IPHONEOS_DEPLOYMENT_TARGET = 16.0 SDKROOT = iphoneos SUPPORTED_PLATFORMS = iphoneos iphonesimulator xros xrsimulator SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO From 8cb8b7572a56200a7e2e156bcbca59b6d109a497 Mon Sep 17 00:00:00 2001 From: Mike Schreiber Date: Fri, 7 Jun 2024 10:30:55 -0700 Subject: [PATCH 2/3] Specify list style --- .../Demos/AliasColorTokensDemoController_SwiftUI.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift b/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift index f27670d9a6..5473c36df9 100644 --- a/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift +++ b/ios/FluentUI.Demo/FluentUI.Demo/Demos/AliasColorTokensDemoController_SwiftUI.swift @@ -33,6 +33,7 @@ struct AliasColorTokensDemoView: View { } } } + .fluentListStyle(.insetGrouped) } @ViewBuilder From 9884a90705d96343f92d78373655572562329f43 Mon Sep 17 00:00:00 2001 From: Mike Schreiber Date: Fri, 7 Jun 2024 13:33:08 -0700 Subject: [PATCH 3/3] Update `Package.swift` --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index e4c3057494..3d38139c84 100644 --- a/Package.swift +++ b/Package.swift @@ -6,7 +6,7 @@ let package = Package( name: "FluentUI", defaultLocalization: "en", platforms: [ - .iOS(.v15), + .iOS(.v16), .macOS(.v12), .visionOS(.v1), ],