1 Star 0 Fork 0

greyCode/SwiftUI-Introspect

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

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 .
Copyright 2019 Timber Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

暂无描述 展开 收起
README
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Swift
1
https://gitee.com/greycode/SwiftUI-Introspect.git
git@gitee.com:greycode/SwiftUI-Introspect.git
greycode
SwiftUI-Introspect
SwiftUI-Introspect
master

搜索帮助