A declarative style interface builder in 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 lets you write intuitive UI code in a collaboration-friendly way.
Xcode storyboards and interface builders have advantages in visual representation, but have critical weaknesses:
- Readability. IB files are designed to be read by Xcode, not humans.
- Collaboration. Due to low readability, it is hard to review changes and resolve conflicts.
- Scope handling. A single storyboard file keeps growing as your codebase grows. If you don't pay enough attention, you'll find a single file contains tens of screens.
- Safety. Interface builders don't know much about your Swift code. Missing references are not caught at compile-time and lead to runtime crash.
IBKit has an intuitive syntax written in Swift code, inspired by SwiftUI, and supports easy integration with Xcode Previews.
- Xcode 11+
- Swift 5.1
- iOS 10
IBKit
requires no external dependencies. Supported installation options are:
# Podfile
user_framework!
target 'YOUR_TARGET_NAME' do
pod 'IBKit'
end
Replace YOUR_TARGET_NAME
and then, in the Podfile
directory, type:
$ pod install
Deployment target 11.0+ is required to install IBKit via CocoaPods.
Create a Package.swift
file.
// 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"])
]
)
Replace SEMVER_TAG
and then type:
$ swift build
Or
Open XcodeProject > File
> Swift Packages
> Add Package Dependency..
Then, Type https://github.com/IBCodeKit/IBKit.git
Conform to InterfaceBuilder
protocol.
class PriceView: UIView, InterfaceBuilder {
var body: Interface {
...
}
}
Declare user interfaces in body
.
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)
}
Instantiate your view (or view controller) using a loadFromIB
method.
let view = PriceView.loadFromIB()
Or load the body using a build
method.
override init(frame: CGRect) {
super.init(frame: frame)
build()
}
- Import the SwiftUI framework to your project. (Import WEAKLY if you support < iOS 13 devices, otherwise it crashes)
Open XcodeProject >
Build Phases
>Link Binary With Libraries
> AddSwifTUI
> Change SwiftUI status toOptional
- Conform to
PreviewProvider
protocol.
#if canImport(SwiftUI) && DEBUG
import SwiftUI
@available(iOS 13.0, *)
struct PriceView_Preview: PreviewProvider {
...
}
#endif
- Implement
PreviewProvider
protocol withPreview
class.
static var previews: some View {
Preview(view: PriceView.loadFromIB())
}
Any pull requests and bug reports are welcome!
Feel free to make a pull request.