Skip to content

Commit

Permalink
Remove iOS 15 support (#2042)
Browse files Browse the repository at this point in the history
* Remove iOS 15 support

* Specify list style

* Update `Package.swift`
  • Loading branch information
mischreiber authored Jun 7, 2024
1 parent d298dac commit 10f944b
Show file tree
Hide file tree
Showing 9 changed files with 13 additions and 95 deletions.
2 changes: 1 addition & 1 deletion MicrosoftFluentUI.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ let package = Package(
name: "FluentUI",
defaultLocalization: "en",
platforms: [
.iOS(.v15),
.iOS(.v16),
.macOS(.v12),
.visionOS(.v1),
],
Expand Down
6 changes: 3 additions & 3 deletions ios/FluentUI.Demo/FluentUI.Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,15 @@ 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 {
colorSection(demoSection)
}
}
}
.background(fluentTheme.swiftUIColor(.backgroundCanvas))
.fluentListStyle(.insetGrouped)
}

@ViewBuilder
Expand Down
2 changes: 1 addition & 1 deletion ios/FluentUI/Core/ControlHostingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
72 changes: 1 addition & 71 deletions ios/FluentUI/Core/FluentThemedHostingController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<AnyView> {

@MainActor required dynamic public override init(rootView: AnyView) {
Expand Down Expand Up @@ -68,13 +35,6 @@ open class FluentThemedHostingController: UIHostingController<AnyView> {
}
}

/// 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) {
Expand All @@ -101,33 +61,3 @@ open class FluentThemedHostingController: UIHostingController<AnyView> {

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]
}
}
}
3 changes: 3 additions & 0 deletions ios/FluentUI/List/FluentList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ public struct FluentList<ListContent: View>: 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))
}
Expand All @@ -66,6 +68,7 @@ public struct FluentList<ListContent: View>: View {
/// Content to render inside the list
private var content: () -> ListContent

@Environment(\.fluentTheme) private var fluentTheme: FluentTheme
}

// MARK: - Environment
Expand Down
1 change: 0 additions & 1 deletion ios/FluentUI/Pill Button Bar/PillButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ open class PillButton: UIButton, TokenizedControlInternal {
updateAttributedTitle()
}

@available(iOS 15, *)
private func updateAttributedTitle() {
let itemTitle = pillBarItem.title
var attributedTitle = AttributedString(itemTitle)
Expand Down
2 changes: 1 addition & 1 deletion ios/xcode/FluentUI_common.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 10f944b

Please sign in to comment.