Allow .introspectTabBarController() on TabView directly

This commit is contained in:
Lois Di Qual 2019-12-02 10:24:55 -08:00
parent fa8e57040a
commit 64be6e0d65
4 changed files with 60 additions and 2 deletions

View File

@ -4,6 +4,7 @@ Changelog
## master
- Allow `.introspectNavigationController()` on NavigationView directly.
- Allow `.introspectTabBarController()` on TabView directly.
## [0.0.4]

View File

@ -85,6 +85,30 @@ public enum Introspect {
return nil
}
/// Finds a previous sibling that is a view controller of the specified type.
/// This method does not inspect siblings recursively.
/// Returns nil if no sibling is of the specified type.
public static func previousSibling<AnyViewControllerType: UIViewController>(
ofType type: AnyViewControllerType.Type,
from entry: UIViewController
) -> AnyViewControllerType? {
guard let parent = entry.parent,
let entryIndex = parent.children.firstIndex(of: entry),
entryIndex > 0
else {
return nil
}
for child in parent.children[0..<entryIndex].reversed() {
if let typed = child as? AnyViewControllerType {
return typed
}
}
return nil
}
/// Finds a next sibling that contains a view of the specified type.
/// This method inspects siblings recursively.
/// Returns nil if no sibling contains the specified type.
@ -337,7 +361,16 @@ extension View {
/// Finds a `UITabBarController` from any SwiftUI view embedded in a `SwiftUI.TabView`
public func introspectTabBarController(customize: @escaping (UITabBarController) -> ()) -> some View {
return inject(IntrospectionViewController(
selector: { $0.tabBarController },
selector: { introspectionViewController in
// Search in ancestors
if let navigationController = introspectionViewController.tabBarController {
return navigationController
}
// Search in siblings
return Introspect.previousSibling(ofType: UITabBarController.self, from: introspectionViewController)
},
customize: customize
))
}

View File

@ -45,6 +45,20 @@ private struct TabTestView: View {
}
}
private struct TabRootTestView: View {
@State private var selection = 0
let spy: () -> Void
var body: some View {
TabView {
Text("Item 1")
.tag(0)
}
.introspectTabBarController { _ in
self.spy()
}
}
}
private struct ListTestView: View {
let spy1: () -> Void
@ -176,6 +190,16 @@ class IntrospectTests: XCTestCase {
wait(for: [expectation], timeout: 1)
}
func testTabViewRoot() {
let expectation = XCTestExpectation()
let view = TabRootTestView(spy: {
expectation.fulfill()
})
TestUtils.present(view: view)
wait(for: [expectation], timeout: 1)
}
func testList() {
let expectation1 = XCTestExpectation()

View File

@ -52,7 +52,7 @@ SwiftUI | UIKit | Introspect | Target
List | UITableView | `.introspectTableView()` | List, or List child
ScrollView | UIScrollView | `.introspectScrollView()` | ScrollView, or ScrollView child
NavigationView | UINavigationController | `.introspectNavigationController()` | NavigationView, or NavigationView child
TabbedView | UITabBarController | `.introspectTabBarController()` | **TabbedView child**
TabView | UITabBarController | `.introspectTabBarController()` | TabView, or TabView child
TextField | UITextField | `.introspectTextField()` | TextField
Toggle | UISwitch | `.introspectSwitch()` | Toggle
Slider | UISlider | `.introspectSlider()` | Slider