Compatibility
- 0.1.2 and master5.35.25.15.04.2
- 0.1.2iOSmacOS(Intel)macOS(ARM)LinuxtvOSwatchOS
- masteriOSmacOS(Intel)macOS(ARM)LinuxtvOSwatchOS
Introspect underlying UIKit components from SwiftUI
Introspect allows you to get the underlying UIKit or AppKit element of a SwiftUI view.
For instance, with Introspect you can access UITableView
to modify separators, or UINavigationController
to customize the tab bar.
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:
IntrospectionView
as an overlay of TextField
UITextField
)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.
Introspect
is meant to be used in production. It does not use any private API. It only inspects the view hierarchy using publicly available methods. The library takes a defensive approach to inspecting the view hierarchy: there is no hard assumption that elements are laid out a certain way, there is no force-cast to UIKit classes, and the introspect()
methods are simply ignored if UIKit views cannot be found.
https://github.com/siteline/SwiftUI-Introspect.git
pod "Introspect"
SwiftUI | UIKit | AppKit | Introspect |
---|---|---|---|
List | UITableView | NSTableView | .introspectTableView() |
ScrollView | UIScrollView | NSScrollView | .introspectScrollView() |
NavigationView | UINavigationController | N/A | .introspectNavigationController() |
Any embedded view | UIViewController | N/A | .introspectViewController() |
TabView | UITabBarController | N/A | .introspectTabBarController() |
TextField | UITextField | NSTextField | .introspectTextField() |
Toggle | UISwitch | N/A | .introspectSwitch() |
Slider | UISlider | NSSlider | .introspectSlider() |
Stepper | UIStepper | NSStepper | .introspectStepper() |
DatePicker | UIDatePicker | NSDatePicker | .introspectDatePicker() |
Picker (SegmentedPickerStyle) | UISegmentedControl | NSSegmentedControl | .introspectSegmentedControl() |
Missing an element? Please create an issue. As a temporary solution, you can implement your own selector.
SwiftUI | Why |
---|---|
Text | Not a UILabel |
Image | Not a UIImageView |
Button | Not a UIButton |
List {
Text("Item 1")
Text("Item 2")
}
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
ScrollView {
Text("Item 2")
}
.introspectScrollView { scrollView in
scrollView.refreshControl = UIRefreshControl()
}
NavigationView {
Text("Item 2")
.introspectNavigationController { navigationController in
navigationController.navigationBar.backgroundColor = .red
}
}
TextField("Text Field", text: $textFieldValue)
.introspectTextField { textField in
textField.layer.backgroundColor = UIColor.red.cgColor
}
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 inject(UIKitIntrospectionView(
selector: { introspectionView in
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
return nil
}
return Introspect.previousSibling(containing: UITextField.self, from: viewHost)
},
customize: customize
))
}
}
You can use any of the following methods to inspect the hierarchy:
Introspect.findChild(ofType:in:)
Introspect.previousSibling(containing:from:)
Introspect.nextSibling(containing:from:)
Introspect.findAncestor(ofType:from:)
Introspect.findHostingView(from:)
Introspect.findViewHost(from:)
$ bundle exec fastlane run increment_version_number bump_type:minor # major|minor|patch
Introspect.podspec
$ git tag -a <VERSION> -m "<MESSAGE>"
$ git push origin --tags
$ bundle exec pod trunk push .