Skip to content

Add .introspectSearchController #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 12, 2023
4 changes: 4 additions & 0 deletions Examples/Showcase/Showcase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
D53071FB29983CF000F1936C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D53071FA29983CF000F1936C /* Assets.xcassets */; };
D53071FE29983CF000F1936C /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D53071FD29983CF000F1936C /* Preview Assets.xcassets */; };
D530720729983DCA00F1936C /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = D530720629983DCA00F1936C /* Introspect */; };
D5B829752999738200920EBD /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B829742999738200920EBD /* Helpers.swift */; };
/* End PBXBuildFile section */

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

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -58,6 +60,7 @@
D530720429983D9300F1936C /* Showcase.entitlements */,
D53071F629983CEF00F1936C /* App.swift */,
D53071F829983CEF00F1936C /* ContentView.swift */,
D5B829742999738200920EBD /* Helpers.swift */,
D53071FA29983CF000F1936C /* Assets.xcassets */,
D53071FC29983CF000F1936C /* Preview Content */,
);
Expand Down Expand Up @@ -153,6 +156,7 @@
buildActionMask = 2147483647;
files = (
D53071F929983CEF00F1936C /* ContentView.swift in Sources */,
D5B829752999738200920EBD /* Helpers.swift in Sources */,
D53071F729983CEF00F1936C /* App.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
37 changes: 28 additions & 9 deletions Examples/Showcase/Showcase/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,34 @@ struct ListShowcase: View {
struct NavigationShowcase: View {
var body: some View {
NavigationView {
VStack {
Text("Customized")
}
#if !os(tvOS)
.navigationBarTitle(Text("Customized"), displayMode: .inline)
#endif
.introspectNavigationController { nvc in
nvc.navigationBar.backgroundColor = .red
}
Text("Customized")
.do {
if #available(iOS 15, tvOS 15, *) {
$0.searchable(text: .constant(""))
} else {
$0
}
}
.do {
#if os(iOS)
if #available(iOS 15, *) {
$0.introspectSearchController { searchController in
searchController.searchBar.backgroundColor = .purple
}
}
#else
$0
#endif
}
#if !os(tvOS)
.navigationBarTitle(Text("Customized"), displayMode: .inline)
#endif
.introspectNavigationController { navigationController in
navigationController.navigationBar.backgroundColor = .red
}
}
.introspectSplitViewController { splitViewController in
splitViewController.preferredDisplayMode = .oneOverSecondary
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions Examples/Showcase/Showcase/Helpers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SwiftUI

extension View {
func `do`<TransformedView: View>(
@ViewBuilder transform: (Self) -> TransformedView
) -> TransformedView {
transform(self)
}
}
12 changes: 12 additions & 0 deletions Introspect/ViewExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ extension View {
customize: customize
))
}

/// Finds a `UISearchController` from a `SwiftUI.View` with a `.searchable` modifier
@available(iOS 15, *)
@available(tvOS, unavailable)
public func introspectSearchController(customize: @escaping (UISearchController) -> ()) -> some View {
introspectNavigationController { navigationController in
let navigationBar = navigationController.navigationBar
if let searchController = navigationBar.topItem?.searchController {
customize(searchController)
}
}
}

/// Finds a `UITableView` from a `SwiftUI.List`, or `SwiftUI.List` child.
public func introspectTableView(customize: @escaping (UITableView) -> ()) -> some View {
Expand Down
36 changes: 35 additions & 1 deletion IntrospectTests/UIKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,28 @@ private struct MapTestView: View {
}
}

#if swift(>=5.5) && !os(tvOS) // swift check needed for some reason for tvOS 14 testing not to fail on CI
@available(iOS 15, *)
@available(tvOS, unavailable)
private struct SearchControllerTestView: View {
@State var searchText = ""
let spy: () -> Void

var body: some View {
NavigationView {
EmptyView()
.searchable(text: $searchText)
.introspectSearchController { searchController in
self.spy()
}
}
.introspectSplitViewController { splitViewController in
splitViewController.preferredDisplayMode = .oneOverSecondary
}
}
}
#endif

class UIKitTests: XCTestCase {
func testNavigation() {

Expand Down Expand Up @@ -647,8 +669,20 @@ class UIKitTests: XCTestCase {
XCTAssertTrue(unwrappedCollectionView.subviews.contains(where: { $0 === unwrappedScrollView }))
}
}
#endif

#if swift(>=5.5) && !os(tvOS)
@available(iOS 15, *)
func testSearchController() {
let expectation = XCTestExpectation()
let view = SearchControllerTestView(spy: {
expectation.fulfill()
})
TestUtils.present(view: view)
wait(for: [expectation], timeout: TestUtils.Constants.timeout)
}
#endif
#endif

@available(iOS 14, tvOS 14, *)
func testMapView() {
let expectation = XCTestExpectation()
Expand Down