GithubHelp home page GithubHelp logo

jhonatn / swiftui-introspect Goto Github PK

View Code? Open in Web Editor NEW

This project forked from siteline/swiftui-introspect

0.0 0.0 0.0 221 KB

Introspect underlying UIKit components from SwiftUI

License: MIT License

Objective-C 0.34% Swift 96.89% Ruby 2.77%

swiftui-introspect's Introduction

Introspect for SwiftUI

CircleCI_Status  GithubCI_Status Siteline_Badge Quintschaf_Badge

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.

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 an overlay of TextField
  • Get the view host of the introspection view (which is alongside the view host of the UITextField)
  • Get the previous 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.

Usage in production

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.

Install

SwiftPM

https://github.com/siteline/SwiftUI-Introspect.git

Cocoapods

pod 'Introspect'

Introspection

Implemented

SwiftUI UIKit AppKit Introspect
NavigationView (StackNavigationViewStyle) UINavigationController N/A .introspectNavigationController()
NavigationView (DoubleColumnNavigationViewStyle) UISplitViewController N/A .introspectSplitViewController()
Any embedded view UIViewController N/A .introspectViewController()
ScrollView UIScrollView NSScrollView .introspectScrollView()
List UITableView NSTableView .introspectTableView()
View in List UITableViewCell NSTableCellView introspectTableViewCell()
TabView UITabBarController NSTabView .introspectTabBarController() (iOS)
.introspectTabView() (macOS)
TextField UITextField NSTextField .introspectTextField()
Toggle UISwitch NSButton .introspectSwitch() (iOS)
.introspectButton() (macOS)
Slider UISlider NSSlider .introspectSlider()
Stepper UIStepper NSStepper .introspectStepper()
DatePicker UIDatePicker NSDatePicker .introspectDatePicker()
Picker (SegmentedPickerStyle) UISegmentedControl NSSegmentedControl .introspectSegmentedControl()
Button N/A NSButton .introspectButton()
ColorPicker UIColorWell NSColorWell .introspectColorWell()
TextEditor UITextView NSTextView .introspectTextView()

Missing an element? Please create an issue. As a temporary solution, you can implement your own selector.

Cannot implement

SwiftUI Affected Frameworks Why
Text UIKit, AppKit Not a UILabel / NSLabel
Image UIKit, AppKit Not a UIImageView / NSImageView
Button UIKit Not a UIButton

Examples

List

List {
    Text("Item 1")
    Text("Item 2")
}
.introspectTableView { tableView in
    tableView.separatorStyle = .none
}
.introspectTableViewCell { cell in
    let backgroundView = UIView()
    backgroundView.backgroundColor = .clear
    cell.selectedBackgroundView = backgroundView
}

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 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.findChildUsingFrame(ofType:in:from:)
  • Introspect.previousSibling(containing:from:)
  • Introspect.nextSibling(containing:from:)
  • Introspect.findAncestor(ofType:from:)
  • Introspect.findHostingView(from:)
  • Introspect.findViewHost(from:)

Releasing

  • Increment version number:
$ bundle exec fastlane run increment_version_number bump_type:minor # major|minor|patch
  • Update changelog with new version
  • Bump version in Introspect.podspec
  • Commit and push changes
  • Tag new version:
$ git tag -a <VERSION> -m "<MESSAGE>"
$ git push origin --tags
  • Push to cocoapods trunk:
$ bundle exec pod trunk push .

swiftui-introspect's People

Contributors

ldiqual avatar jannthomas avatar splittydev avatar renovate[bot] avatar aaryankotharii avatar orospakr avatar ethanbonin avatar dmonagle avatar jevonmao avatar joelpoloney avatar nuplay avatar kaishin avatar simba909 avatar vukrado avatar dependabot[bot] avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.