Go to file
Lois Di Qual b54abf2340 Bump to 0.0.2 2019-11-29 11:30:04 -08:00
Introspect Fix Package.swift 2019-11-29 11:28:47 -08:00
Introspect.xcodeproj Add more tests 2019-11-27 10:31:01 -08:00
Introspect.xcworkspace Add TextField 2019-11-27 09:10:10 -08:00
IntrospectExamples Root introspection 2019-11-27 09:52:38 -08:00
IntrospectTests DatePicker tests 2019-11-27 10:34:26 -08:00
docs Add diagram 2019-11-27 11:32:07 -08:00
.gitignore Add diagram 2019-11-27 11:32:07 -08:00
.ruby-version Add TextField 2019-11-27 09:10:10 -08:00
Gemfile Add TextField 2019-11-27 09:10:10 -08:00
Gemfile.lock Add TextField 2019-11-27 09:10:10 -08:00
Introspect.podspec Bump to 0.0.2 2019-11-29 11:30:04 -08:00
LICENSE Add license + examples 2019-11-27 09:59:10 -08:00
Package.swift Fix Package.swift 2019-11-29 11:28:47 -08:00
Podfile Add TextField 2019-11-27 09:10:10 -08:00
Podfile.lock Add TextField 2019-11-27 09:10:10 -08:00
README.md Add diagram 2019-11-27 11:32:07 -08:00

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 of TextField
  • 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:)