Skip to content

Commit a1a97a8

Browse files
Add introspectSearchController (#129)
Co-authored-by: David Roman <2538074+davdroman@users.noreply.github.com>
1 parent be01237 commit a1a97a8

File tree

5 files changed

+88
-10
lines changed

5 files changed

+88
-10
lines changed

Examples/Showcase/Showcase.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
D53071FB29983CF000F1936C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D53071FA29983CF000F1936C /* Assets.xcassets */; };
1313
D53071FE29983CF000F1936C /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D53071FD29983CF000F1936C /* Preview Assets.xcassets */; };
1414
D530720729983DCA00F1936C /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = D530720629983DCA00F1936C /* Introspect */; };
15+
D5B829752999738200920EBD /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B829742999738200920EBD /* Helpers.swift */; };
1516
/* End PBXBuildFile section */
1617

1718
/* Begin PBXFileReference section */
@@ -21,6 +22,7 @@
2122
D53071FA29983CF000F1936C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
2223
D53071FD29983CF000F1936C /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
2324
D530720429983D9300F1936C /* Showcase.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Showcase.entitlements; sourceTree = "<group>"; };
25+
D5B829742999738200920EBD /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
2426
/* End PBXFileReference section */
2527

2628
/* Begin PBXFrameworksBuildPhase section */
@@ -58,6 +60,7 @@
5860
D530720429983D9300F1936C /* Showcase.entitlements */,
5961
D53071F629983CEF00F1936C /* App.swift */,
6062
D53071F829983CEF00F1936C /* ContentView.swift */,
63+
D5B829742999738200920EBD /* Helpers.swift */,
6164
D53071FA29983CF000F1936C /* Assets.xcassets */,
6265
D53071FC29983CF000F1936C /* Preview Content */,
6366
);
@@ -153,6 +156,7 @@
153156
buildActionMask = 2147483647;
154157
files = (
155158
D53071F929983CEF00F1936C /* ContentView.swift in Sources */,
159+
D5B829752999738200920EBD /* Helpers.swift in Sources */,
156160
D53071F729983CEF00F1936C /* App.swift in Sources */,
157161
);
158162
runOnlyForDeploymentPostprocessing = 0;

Examples/Showcase/Showcase/ContentView.swift

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,34 @@ struct ListShowcase: View {
7272
struct NavigationShowcase: View {
7373
var body: some View {
7474
NavigationView {
75-
VStack {
76-
Text("Customized")
77-
}
78-
#if !os(tvOS)
79-
.navigationBarTitle(Text("Customized"), displayMode: .inline)
80-
#endif
81-
.introspectNavigationController { nvc in
82-
nvc.navigationBar.backgroundColor = .red
83-
}
75+
Text("Customized")
76+
.do {
77+
if #available(iOS 15, tvOS 15, *) {
78+
$0.searchable(text: .constant(""))
79+
} else {
80+
$0
81+
}
82+
}
83+
.do {
84+
#if os(iOS)
85+
if #available(iOS 15, *) {
86+
$0.introspectSearchController { searchController in
87+
searchController.searchBar.backgroundColor = .purple
88+
}
89+
}
90+
#else
91+
$0
92+
#endif
93+
}
94+
#if !os(tvOS)
95+
.navigationBarTitle(Text("Customized"), displayMode: .inline)
96+
#endif
97+
.introspectNavigationController { navigationController in
98+
navigationController.navigationBar.backgroundColor = .red
99+
}
100+
}
101+
.introspectSplitViewController { splitViewController in
102+
splitViewController.preferredDisplayMode = .oneOverSecondary
84103
}
85104
}
86105
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import SwiftUI
2+
3+
extension View {
4+
func `do`<TransformedView: View>(
5+
@ViewBuilder transform: (Self) -> TransformedView
6+
) -> TransformedView {
7+
transform(self)
8+
}
9+
}

Introspect/ViewExtensions.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ extension View {
8484
customize: customize
8585
))
8686
}
87+
88+
/// Finds a `UISearchController` from a `SwiftUI.View` with a `.searchable` modifier
89+
@available(iOS 15, *)
90+
@available(tvOS, unavailable)
91+
public func introspectSearchController(customize: @escaping (UISearchController) -> ()) -> some View {
92+
introspectNavigationController { navigationController in
93+
let navigationBar = navigationController.navigationBar
94+
if let searchController = navigationBar.topItem?.searchController {
95+
customize(searchController)
96+
}
97+
}
98+
}
8799

88100
/// Finds a `UITableView` from a `SwiftUI.List`, or `SwiftUI.List` child.
89101
public func introspectTableView(customize: @escaping (UITableView) -> ()) -> some View {

IntrospectTests/UIKitTests.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,28 @@ private struct MapTestView: View {
379379
}
380380
}
381381

382+
#if swift(>=5.5) && !os(tvOS) // swift check needed for some reason for tvOS 14 testing not to fail on CI
383+
@available(iOS 15, *)
384+
@available(tvOS, unavailable)
385+
private struct SearchControllerTestView: View {
386+
@State var searchText = ""
387+
let spy: () -> Void
388+
389+
var body: some View {
390+
NavigationView {
391+
EmptyView()
392+
.searchable(text: $searchText)
393+
.introspectSearchController { searchController in
394+
self.spy()
395+
}
396+
}
397+
.introspectSplitViewController { splitViewController in
398+
splitViewController.preferredDisplayMode = .oneOverSecondary
399+
}
400+
}
401+
}
402+
#endif
403+
382404
class UIKitTests: XCTestCase {
383405
func testNavigation() {
384406

@@ -647,8 +669,20 @@ class UIKitTests: XCTestCase {
647669
XCTAssertTrue(unwrappedCollectionView.subviews.contains(where: { $0 === unwrappedScrollView }))
648670
}
649671
}
650-
#endif
651672

673+
#if swift(>=5.5) && !os(tvOS)
674+
@available(iOS 15, *)
675+
func testSearchController() {
676+
let expectation = XCTestExpectation()
677+
let view = SearchControllerTestView(spy: {
678+
expectation.fulfill()
679+
})
680+
TestUtils.present(view: view)
681+
wait(for: [expectation], timeout: TestUtils.Constants.timeout)
682+
}
683+
#endif
684+
#endif
685+
652686
@available(iOS 14, tvOS 14, *)
653687
func testMapView() {
654688
let expectation = XCTestExpectation()

0 commit comments

Comments
 (0)