Skip to content

Commit 2c08383

Browse files
Reduce complexity of modal style (#602)
* Reduce complexity of modal style * Remove underscore from withAdditionalConfiguration * Change custom to noop * Use none case for custom modal presentation style * Remove extraneous availability conditionals * Always set isModalInPresentation to true
1 parent 4f738f8 commit 2c08383

File tree

2 files changed

+34
-194
lines changed

2 files changed

+34
-194
lines changed

Sources/Nodes/ViewControllable/UIKit/UIViewController+ModalStyle.swift

+18-74
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public struct ModalStyle {
3030
/// The ``UIModalPresentationStyle.formSheet`` behavior.
3131
case form
3232

33-
/// The ``UIModalPresentationStyle.custom`` behavior.
33+
/// NOT INTENDED FOR USE
3434
case custom
3535
}
3636

@@ -48,25 +48,15 @@ public struct ModalStyle {
4848
/// The ``ModalStyle`` behavior.
4949
public let behavior: Behavior
5050

51-
/// Specifies whether control of status bar appearance is enabled.
52-
public let controlStatusBarAppearance: Bool
53-
54-
/// Specifies whether interactive dismissal is allowed.
55-
public let allowInteractiveDismissal: Bool
56-
5751
/// An array of closures containing additional modal style configuration. Each closure is called with the
5852
/// ``ViewControllable`` instance to configure.
5953
public let configuration: [(ViewControllable) -> Void]
6054

6155
private init(
6256
behavior: Behavior,
63-
controlStatusBarAppearance: Bool,
64-
allowInteractiveDismissal: Bool,
6557
configuration: [(ViewControllable) -> Void] = []
6658
) {
6759
self.behavior = behavior
68-
self.controlStatusBarAppearance = controlStatusBarAppearance
69-
self.allowInteractiveDismissal = allowInteractiveDismissal
7060
self.configuration = configuration
7161
}
7262

@@ -76,51 +66,32 @@ public struct ModalStyle {
7666
/// the presentation completes. Presentation of a full screen view is expected
7767
/// since uncovered underlying content will disappear.
7868
///
79-
/// - Returns: A ``ModalStyle`` instance with `behavior` set to `.cover`, `controlStatusBarAppearance` set to
80-
/// `true` and `allowInteractiveDismissal` set to `false`.
69+
/// - Returns: A ``ModalStyle`` instance with `behavior` set to `.cover`.
8170
public static func cover() -> Self {
82-
Self(behavior: .cover,
83-
controlStatusBarAppearance: true,
84-
allowInteractiveDismissal: false)
71+
Self(behavior: .cover)
8572
}
8673

8774
/// A factory method that creates a ``ModalStyle`` with overlay behavior.
8875
///
8976
/// Overlays the presenting view controller which remains visible.
9077
/// All content not covered by the presented view controller will also be visible.
9178
///
92-
/// - Parameter controlStatusBarAppearance: A Boolean value specifying whether the presented view controller
93-
/// takes over control of status bar appearance from the presenting view controller.
94-
///
95-
/// - Returns: A ``ModalStyle`` instance with `behavior` set to `.overlay`, the given
96-
/// `controlStatusBarAppearance` and `allowInteractiveDismissal` set to `false`.
97-
public static func overlay(
98-
controlStatusBarAppearance: Bool = false
99-
) -> Self {
100-
Self(behavior: .overlay,
101-
controlStatusBarAppearance: controlStatusBarAppearance,
102-
allowInteractiveDismissal: false)
79+
/// - Returns: A ``ModalStyle`` instance with `behavior` set to `.overlay`.
80+
public static func overlay() -> Self {
81+
Self(behavior: .overlay)
10382
}
10483

10584
/// A factory method that creates a ``ModalStyle`` with page or form behavior.
10685
///
10786
/// Partially covers the presenting view controller which remains visible.
10887
/// All content not covered by the presented view controller will also be visible.
10988
///
110-
/// - Parameters:
111-
/// - sheetStyle: The SheetStyle used to specify page or form behavior.
112-
/// - controlStatusBarAppearance: A Boolean value specifying whether the presented view controller
113-
/// takes over control of status bar appearance from the presenting view controller.
114-
/// - allowInteractiveDismissal: A Boolean value specifying whether the presentation allows interactive
115-
/// dismissal.
89+
/// - Parameter sheetStyle: The SheetStyle used to specify page or form behavior.
11690
///
117-
/// - Returns: A ``ModalStyle`` instance with `behavior` set to the given `sheetStyle`, the given
118-
/// `controlStatusBarAppearance` and the given `allowInteractiveDismissal`.
91+
/// - Returns: A ``ModalStyle`` instance with `behavior` set to the given `sheetStyle`.
11992
@available(tvOS, unavailable)
12093
public static func sheet(
121-
style sheetStyle: SheetStyle = .page,
122-
controlStatusBarAppearance: Bool = false,
123-
allowInteractiveDismissal: Bool = false
94+
style sheetStyle: SheetStyle = .page
12495
) -> Self {
12596
let behavior: Behavior
12697
switch sheetStyle {
@@ -129,42 +100,20 @@ public struct ModalStyle {
129100
case .form:
130101
behavior = .form
131102
}
132-
return Self(behavior: behavior,
133-
controlStatusBarAppearance: controlStatusBarAppearance,
134-
allowInteractiveDismissal: allowInteractiveDismissal)
103+
return Self(behavior: behavior)
135104
}
136105

137-
/// A factory method that creates a ``ModalStyle`` with custom behavior.
138-
///
139-
/// Custom presentation controlled by ``UIViewControllerTransitioningDelegate``
140-
/// and ``UIViewControllerAnimatedTransitioning`` object(s).
141-
///
142-
/// - Parameter controlStatusBarAppearance: A Boolean value specifying whether the presented view controller
143-
/// takes over control of status bar appearance from the presenting view controller.
144-
///
145-
/// - Returns: A ``ModalStyle`` instance with `behavior` set to `.custom`, the given
146-
/// `controlStatusBarAppearance` and `allowInteractiveDismissal` set to `false`.
147-
public static func custom(
148-
controlStatusBarAppearance: Bool = false
149-
) -> Self {
150-
Self(behavior: .custom,
151-
controlStatusBarAppearance: controlStatusBarAppearance,
152-
allowInteractiveDismissal: false)
106+
/// NOT INTENDED FOR USE
107+
public static func custom() -> Self {
108+
Self(behavior: .custom)
153109
}
154110

155-
// swiftlint:disable identifier_name
156-
157-
/// DEPRECATED - DO NOT USE
158-
public func _withAdditionalConfiguration(
111+
/// NOT INTENDED FOR USE
112+
public func withAdditionalConfiguration(
159113
configuration additionalConfiguration: @escaping (ViewControllable) -> Void
160114
) -> Self {
161-
Self(behavior: behavior,
162-
controlStatusBarAppearance: controlStatusBarAppearance,
163-
allowInteractiveDismissal: allowInteractiveDismissal,
164-
configuration: configuration + [additionalConfiguration])
115+
Self(behavior: behavior, configuration: configuration + [additionalConfiguration])
165116
}
166-
167-
// swiftlint:enable identifier_name
168117
}
169118

170119
extension UIViewController {
@@ -188,14 +137,9 @@ extension UIViewController {
188137
modalPresentationStyle = .formSheet
189138
#endif
190139
case .custom:
191-
modalPresentationStyle = .custom
192-
}
193-
#if !os(tvOS)
194-
modalPresentationCapturesStatusBarAppearance = modalStyle.controlStatusBarAppearance
195-
#endif
196-
if #available(iOS 13.0, tvOS 13.0, *) {
197-
isModalInPresentation = !modalStyle.allowInteractiveDismissal
140+
modalPresentationStyle = .none
198141
}
142+
isModalInPresentation = true
199143
modalStyle.configuration.forEach { $0(self) }
200144
return self
201145
}

Tests/NodesTests/ViewControllable/UIKit/UIViewController+ModalStyleTests.swift

+16-120
Original file line numberDiff line numberDiff line change
@@ -16,175 +16,71 @@ final class UIViewControllerModalStyleTests: XCTestCase {
1616
func testCover() {
1717

1818
let modalStyle: ModalStyle = .cover()
19-
let viewController: UIViewController = givenViewController(with: modalStyle)
20-
2119
expect(modalStyle.behavior) == .cover
22-
expect(modalStyle.controlStatusBarAppearance) == true
23-
expect(modalStyle.allowInteractiveDismissal) == false
24-
25-
expect(viewController.modalPresentationStyle) == .fullScreen
26-
if #available(macCatalyst 13.0, *) {
27-
#if !os(tvOS)
28-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == true
29-
#endif
30-
}
31-
if #available(macCatalyst 13.0, iOS 13.0, tvOS 13.0, *) {
32-
expect(viewController.isModalInPresentation) == true
33-
}
34-
}
35-
36-
func testOverlay() {
3720

38-
let modalStyle: ModalStyle = .overlay(controlStatusBarAppearance: true)
3921
let viewController: UIViewController = givenViewController(with: modalStyle)
22+
expect(viewController.modalPresentationStyle) == .fullScreen
4023

41-
expect(modalStyle.behavior) == ModalStyle.Behavior.overlay
42-
expect(modalStyle.controlStatusBarAppearance) == true
43-
expect(modalStyle.allowInteractiveDismissal) == false
44-
45-
expect(viewController.modalPresentationStyle) == .overFullScreen
46-
if #available(macCatalyst 13.0, *) {
47-
#if !os(tvOS)
48-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == true
49-
#endif
50-
}
51-
if #available(macCatalyst 13.0, iOS 13.0, tvOS 13.0, *) {
24+
if #available(iOS 13.0, tvOS 13.0, *) {
5225
expect(viewController.isModalInPresentation) == true
5326
}
5427
}
5528

5629
func testOverlayWithDefaults() {
5730

5831
let modalStyle: ModalStyle = .overlay()
59-
let viewController: UIViewController = givenViewController(with: modalStyle)
60-
6132
expect(modalStyle.behavior) == ModalStyle.Behavior.overlay
62-
expect(modalStyle.controlStatusBarAppearance) == false
63-
expect(modalStyle.allowInteractiveDismissal) == false
6433

34+
let viewController: UIViewController = givenViewController(with: modalStyle)
6535
expect(viewController.modalPresentationStyle) == .overFullScreen
66-
if #available(macCatalyst 13.0, *) {
67-
#if !os(tvOS)
68-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == false
69-
#endif
70-
}
71-
if #available(macCatalyst 13.0, iOS 13.0, tvOS 13.0, *) {
36+
37+
if #available(iOS 13.0, tvOS 13.0, *) {
7238
expect(viewController.isModalInPresentation) == true
7339
}
7440
}
7541

76-
@available(macCatalyst 13.0, iOS 13.0, *)
42+
@available(iOS 13.0, *)
7743
@available(tvOS, unavailable)
7844
func testPageSheet() {
7945

80-
let modalStyle: ModalStyle = .sheet(style: .page,
81-
controlStatusBarAppearance: true,
82-
allowInteractiveDismissal: true)
83-
let viewController: UIViewController = givenViewController(with: modalStyle)
84-
85-
expect(modalStyle.behavior) == .page
86-
expect(modalStyle.controlStatusBarAppearance) == true
87-
expect(modalStyle.allowInteractiveDismissal) == true
88-
89-
expect(viewController.modalPresentationStyle) == .pageSheet
90-
if #available(macCatalyst 13.0, *) {
91-
#if !os(tvOS)
92-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == true
93-
#endif
94-
}
95-
expect(viewController.isModalInPresentation) == false
96-
}
97-
98-
@available(macCatalyst 13.0, iOS 13.0, *)
99-
@available(tvOS, unavailable)
100-
func testPageSheetWithDefaults() {
101-
10246
let modalStyle: ModalStyle = .sheet(style: .page)
103-
let viewController: UIViewController = givenViewController(with: modalStyle)
104-
10547
expect(modalStyle.behavior) == .page
106-
expect(modalStyle.controlStatusBarAppearance) == false
107-
expect(modalStyle.allowInteractiveDismissal) == false
10848

49+
let viewController: UIViewController = givenViewController(with: modalStyle)
10950
expect(viewController.modalPresentationStyle) == .pageSheet
110-
if #available(macCatalyst 13.0, *) {
111-
#if !os(tvOS)
112-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == false
113-
#endif
114-
}
11551
expect(viewController.isModalInPresentation) == true
11652
}
11753

118-
@available(macCatalyst 13.0, iOS 13.0, *)
54+
@available(iOS 13.0, *)
11955
@available(tvOS, unavailable)
12056
func testFormSheet() {
12157

122-
let modalStyle: ModalStyle = .sheet(style: .form,
123-
controlStatusBarAppearance: true,
124-
allowInteractiveDismissal: true)
125-
let viewController: UIViewController = givenViewController(with: modalStyle)
126-
127-
expect(modalStyle.behavior) == .form
128-
expect(modalStyle.controlStatusBarAppearance) == true
129-
expect(modalStyle.allowInteractiveDismissal) == true
130-
131-
expect(viewController.modalPresentationStyle) == .formSheet
132-
if #available(macCatalyst 13.0, *) {
133-
#if !os(tvOS)
134-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == true
135-
#endif
136-
}
137-
expect(viewController.isModalInPresentation) == false
138-
}
139-
140-
@available(macCatalyst 13.0, iOS 13.0, *)
141-
@available(tvOS, unavailable)
142-
func testFormSheetWithDefaults() {
143-
14458
let modalStyle: ModalStyle = .sheet(style: .form)
145-
let viewController: UIViewController = givenViewController(with: modalStyle)
146-
14759
expect(modalStyle.behavior) == .form
148-
expect(modalStyle.controlStatusBarAppearance) == false
149-
expect(modalStyle.allowInteractiveDismissal) == false
15060

61+
let viewController: UIViewController = givenViewController(with: modalStyle)
15162
expect(viewController.modalPresentationStyle) == .formSheet
152-
if #available(macCatalyst 13.0, *) {
153-
#if !os(tvOS)
154-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == false
155-
#endif
156-
}
15763
expect(viewController.isModalInPresentation) == true
15864
}
15965

16066
func testCustom() {
16167

16268
let modalStyle: ModalStyle = .custom()
163-
let viewController: UIViewController = givenViewController(with: modalStyle)
164-
16569
expect(modalStyle.behavior) == .custom
166-
expect(modalStyle.controlStatusBarAppearance) == false
167-
expect(modalStyle.allowInteractiveDismissal) == false
168-
169-
expect(viewController.modalPresentationStyle) == .custom
170-
if #available(macCatalyst 13.0, *) {
171-
#if !os(tvOS)
172-
expect(viewController.modalPresentationCapturesStatusBarAppearance) == false
173-
#endif
174-
}
175-
if #available(macCatalyst 13.0, iOS 13.0, tvOS 13.0, *) {
176-
expect(viewController.isModalInPresentation) == true
177-
}
70+
71+
let viewController: UIViewController = givenViewController(with: modalStyle)
72+
expect(viewController.modalPresentationStyle) == UIModalPresentationStyle.none
73+
expect(viewController.isModalInPresentation) == true
17874
}
17975

18076
func testAdditionalConfiguration() {
18177
var additionalConfiguration1: [UIViewController] = []
18278
var additionalConfiguration2: [UIViewController] = []
18379
var additionalConfiguration3: [UIViewController] = []
18480
let modalStyle: ModalStyle = .cover()
185-
._withAdditionalConfiguration { additionalConfiguration1.append($0._asUIViewController()) }
186-
._withAdditionalConfiguration { additionalConfiguration2.append($0._asUIViewController()) }
187-
._withAdditionalConfiguration { additionalConfiguration3.append($0._asUIViewController()) }
81+
.withAdditionalConfiguration { additionalConfiguration1.append($0._asUIViewController()) }
82+
.withAdditionalConfiguration { additionalConfiguration2.append($0._asUIViewController()) }
83+
.withAdditionalConfiguration { additionalConfiguration3.append($0._asUIViewController()) }
18884
let viewController: UIViewController = givenViewController(with: modalStyle)
18985
expect(additionalConfiguration1) == [viewController]
19086
expect(additionalConfiguration2) == [viewController]

0 commit comments

Comments
 (0)