![]() |
||
---|---|---|
Introspect | ||
Introspect.xcodeproj | ||
Introspect.xcworkspace | ||
IntrospectExamples | ||
IntrospectTests | ||
docs | ||
.gitignore | ||
.ruby-version | ||
Gemfile | ||
Gemfile.lock | ||
Introspect.podspec | ||
LICENSE | ||
Package.swift | ||
Podfile | ||
Podfile.lock | ||
README.md |
README.md
Introspect for SwiftUI
Introspect allows you to get the underlying UIKit element of a SwiftUI view.
For instance, with Introspect you can access UITableView
to modify separators, or UINavigationController
to customize the tab bar.
How it works
Introspect works by adding a custom IntrospectionView
to the view hierarchy, then looking into the UIKit hierarchy to find the relevant view.
For instance, when introspecting a TextField
, it will:
- Add
IntrospectionView
as the background ofTextField
- Get the view host of the introspection view (which is alongside the view host of the
UITextField
) - Get the next sibling containing
UITextField
Please note that this introspection method might break in future SwiftUI releases. Future implementations might not use the same hierarchy, or might not use UIKit elements that are being looked for. Though the library is unlikely to crash, the .introspect()
method will not be called in those cases.
Install
SwiftPM
https://github.com/timbersoftware/SwiftUI-Introspect.git
Cocoapods
pod "Introspect"
Introspection
Implemented
SwiftUI | UIKit | Introspect | Target |
---|---|---|---|
List | UITableView | .introspectTableView() |
List, or List child |
ScrollView | UIScrollView | .introspectScrollView() |
ScrollView, or ScrollView child |
NavigationView | UINavigationController | .introspectNavigationController() |
NavigationView child |
TabbedView | UITabBarController | .introspectTabBarController() |
TabbedView child |
TextField | UITextField | .introspectTextField() |
TextField |
Toggle | UISwitch | .introspectSwitch() |
Toggle |
Slider | UISlider | .introspectSlider() |
Slider |
Stepper | UIStepper | .introspectStepper() |
Stepper |
DatePicker | UIDatePicker | .introspectDatePicker() |
DatePicker |
Missing an element? Please create an issue. As a temporary solution, you can implement your own selector.
Cannot implement
SwiftUI | Why |
---|---|
Text | Not a UILabel |
Image | Not a UIImageView |
SegmentedControl | Not a UISegmentedControl |
Button | Not a UIButton |
Examples
List
List {
Text("Item 1")
Text("Item 2")
}
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
ScrollView
ScrollView {
Text("Item 2")
}
.introspectScrollView { scrollView in
scrollView.refreshControl = UIRefreshControl()
}
NavigationView
NavigationView {
Text("Item 2")
.introspectNavigationController { navigationController in
navigationController.navigationBar.backgroundColor = .red
}
}
TextField
TextField("Text Field", text: $textFieldValue)
.introspectTextField { textField in
textField.layer.backgroundColor = UIColor.red.cgColor
}
Implement your own selector
Missing an element? Please create an issue.
In case Introspect doesn't support the SwiftUI element that you're looking for, you can implement your own selector. For example, to look for a UITextField
:
extension View {
public func introspectTextField(customize: @escaping (UITextField) -> ()) -> some View {
return self.background(IntrospectionView(
selector: { introspectionView in
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
return nil
}
return Introspect.firstSibling(containing: UITextField.self, from: viewHost)
},
customize: customize
))
}
}
You can use any of the following methods to inspect the hierarchy:
Introspect.findChild(ofType:in:)
Introspect.firstSibling(containing:from:)
Introspect.findAncestor(ofType:from:)
Introspect.findHostingView(from:)
Introspect.findViewHost(from:)