IBKit 0.3.0

IBKit 0.3.0

Nate Kim 维护。



IBKit 0.3.0

  • Nate Kim

Swift CocoaPods Platform Build Status

IBKit

Swift 中的声明式界面构建器。

var body: Interface {
  ViewGroup {
    UIImageView()
      .assign(to: \Self.thumbnailImageView, on: self)

    UIView {
      UILabel()
        .font(.preferredFont(forTextStyle: .title2))
        .textColor(.label)

      UILabel()
        .font(.preferredFont(forTextStyle: .caption1))
        .textColor(.secondaryLabel)
        .assign(to: \Self.additionalTextLabel, on: self)

      UIImageView()
        .image(UIImage(named: "ic_passenger")?.withRenderingMode(.alwaysTemplate))
        .tintColor(.secondaryLabel)

      UILabel()
        .font(.preferredFont(forTextStyle: .caption1))
        .textColor(.secondaryLabel)
    }
    .backgroundColor(.systemBackground)

    PriceView()

    UIView()
      .backgroundColor(.separator)
  }
}

为何选择 IBKit

Storyboard, XIB 是一种 XML 文件。然而,你是否亲手编辑过 storyboard 或 XIB?可能没有。阅读和编辑很难。Storyboard 和 XIB 具有许多麻烦的特性,如 iddestination 等。此外,它们包含相当大量的 XML。因此,当有人打开带有其修改的 pull request 时,人们无法看到发生了哪些更改。

更糟的是,Storyboard 随着时间的推移会不断变大。它们可能一开始很小,但当你添加了另一个视图控制器,再添加另一个,然后再添加另一个,突然你就意识到你在一个文件中有了十个屏幕的数据,任何源控制更改都会变得非常痛苦。

此外,Interface Builder 对 Swift 代码和反之亦然的了解不多。这使得有很多不安全的功能。例如,我们从 IB 拖动到我们的代码中连接某个功能。那么如果我们从代码中删除了该功能怎么办?代码仍然可以编译通过,但程序会崩溃!

最后,Interface Builder 的行为并不像预期的那样。从 xib 设置的命名颜色在 viewDidLoadviewWillAppearawakeFromNib 方法中不能更改。

尽管如此,Storyboard, XIB 有强大的优势。它提供了非常好的视觉表示。而且使用简单。当你以编程方式创建 ViewController 时,会有很多代码而且看起来很冗长。

基本上,IBKit 是一种用于程序化 UI 的工具。通过使用声明式风格,您可以直观地理解 UI。此外,IBKit 有一个简单的 Preview 类用于 Xcode 预览。您可以轻松地提供实时视觉表示。

IBKit 是实现 UI 的最直接、最简单的方式。

要求

  • Xcode 11+
  • Swift 5.1
  • iOS 10

安装

IBKit 不包含任何外部依赖。目前支持以下选项

Cocoapods

# Podfile
user_framework!
target 'YOUR_TARGET_NAME' do
    pod 'IBKit'
end

替换 YOUR_TARGET_NAME,然后在 Podfile 目录中输入

$ pod install

使用 Cocoapods 安装 IBKit 需要 11.0+ 的部署目标。

Swift 包管理器

创建一个 Package.swift 文件。

// swift-tools-version:5.1

import PackageDescription

let package = Package(
  name: "NAME",
  dependencies: [
    .package(url: "https://github.com/IBCodeKit/IBKit.git", from: "SEMVER_TAG")
  ],
  targets: [
    .target(name: "NAME", dependencies: ["IBKit"])
  ]
)

替换 SEMVER_TAG 然后输入

$ swift build

或者

在 XcodeProject 中,打开 File > Swift Packages > Add Package Dependency..

然后输入 https://github.com/IBCodeKit/IBKit.git

使用方法

遵守 InterfaceBuilder 协议。

class PriceView: UIView, InterfaceBuilder {
  var body: Interface {
    ...
  }
}

在主体中声明用户界面。

ViewGroup {
  UIImageView()
    .assign(to: \Self.thumbnailImageView, on: self)

  UIView {
    UILabel()
      .font(.preferredFont(forTextStyle: .title2))
      .textColor(.label)

    UILabel()
      .font(.preferredFont(forTextStyle: .caption1))
      .textColor(.secondaryLabel)
      .didAwakeFromBuilder { views in
        views.this.topAnchor.constraint(equalTo: views.superview.topAnchor).isActive = true
        views.this.trailingAnchor.constraint(equalTo: views.superview.trailingAnchor).isActive = true
      }
  }
  .backgroundColor(.systemBackground)
}

使用 loadFromIB 方法实例化您的视图(控制器)。

let view = PriceView.loadFromIB()

或者使用 build 方法加载主体。

override init(frame: CGRect) {
  super.init(frame: frame)
  build()
}

Xcode 预览

  1. 要使用 Xcode 预览,您的项目中必须弱导入 SwiftUI 框架。

    在 XcodeProject 中,打开 Build Phases > Link Binary With Libraries > 添加 SwifTUI > 将 SwiftUI 状态更改为 Optional

  2. 遵守 PreviewProvider 协议。

#if canImport(SwiftUI) && DEBUG
import SwiftUI

@available(iOS 13.0, *)
struct PriceView_Preview: PreviewProvider {
  ...
}
#endif
  1. 使用 Preview 类实现 PreviewProvider 协议。
static var previews: some View {
  Preview(view: PriceView.loadFromIB())
}

贡献

欢迎提交代码请求和错误报告!

请随时提交代码请求。