核心优势 📊
✅ 存量项目现代化 渐进式改造现有 UIKit 代码
✅ 开发体验革新 在 UIKit 上获得 SwiftUI 的开发效率
✅ 完全掌控力 保留 UIKit 的底层控制能力
✅ 深度整合 无缝兼容 Objective-C/Swift 代码
✅ 企业级适配 非 SwiftUI 项目的完美解决方案
功能特性 ✨
🌟 链式语法革命
let stackView = UIStackView()
.axis(.vertical)
.spacing(10)
.alignment(.center)
.distribution(.fillEqually)
.padding()
.separator(color: .red, size: CGSize(width: 20, height: 2))
🎮 智能手势系统
let view = UIView()
.onGesture(.doubleTap) { _ in print("双击触发") }
.onGesture(.swipe(.up)) { _ in showMenu() }
- 声明式动画引擎
withAnimation(.spring(duration: 0.8)) {
view.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
} completion: { _ in /* 动画收尾逻辑 */ }
📐 多模式布局
// 自动布局 | Auto Layout
.frame(width: 100, minHeight: 200)
// SnapKit
.snp { make in
make.with.height.equalTo(30)
}
// 父控件前布局
UIView().left(to: superView.leftAnchor, offset: 30)
.top(to: superView, offset: 30)
.fill(to: superView)
组件构建示例
UIView Build
Basics
let view = UIView()
.backgroundColor(.clear)
.border(.orange)
.border(.black, 2)
.cornerRadius(8)
.alpha(0.5)
.opacity(0.5)
.hidden(false)
.hidden()
.tag(100)
.userInteractionEnabled(false)
.userInteractionEnabled()
.shadow(color: .black, radius: 3, opacity: 0.3, offset: .zero)
.backgroundView {
UIView()
}
and more ...
- Layout
//自动布局 | Auto Layout
let brother = UIView()
.frame(width: 100, height: 200)
.frame(width: 20)
.frame(height: 100)
.frame(minWidth: 50)
.frame(maxWidth: 200)
.snp { make in // if Import SnapKit
make.width.equalTo(100)
make.height.equalTo(200)
}
//父控件前布局 | Pre-Superview Layout
let view = UIView()
.left(to: superView.leftAnchor, offset: 30)
.top(to: superView, offset: 30)
.fill(to: superView)
.fill(to: brother, UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
.leading(to: superView)
.bottom(to: superView)
.width(20)
.width(to: view, multiplier: 1.2)
superView.addSubview(brother)
superView.addSubview(view)
- Gesture
let view = UIView()
.onGesture(.tap) { _ in
// action
}
.onGesture(.tap, action:gestureAction)
.onGesture(.doubleTap, action: onTapGestureAction)
.onGesture(.pan, action: onPanGestureAction)
.onGesture(.rotation, action: onRelocationGestureAction)
.onGesture(.pinch, action: onPinchGestureAction)
.onGesture(.swipe(direction: .down), action: onSwipeGestureAction)
.onGesture(.longPress(minimumDuration: 1), action: onLongPressGestureAction)
func onGestureAction(_ gesture: UIGestureRecognizer) { }
func onTapGestureAction(_ gesture: UITapGestureRecognizer) { }
func onPanGestureAction(_ gesture: UIPanGestureRecognizer) { }
func onSwipeGestureAction(_ gesture: UISwipeGestureRecognizer) { }
func onPinchGestureAction(_ gesture: UIPinchGestureRecognizer) { }
func onRelocationGestureAction(_ gesture: UIRotationGestureRecognizer) { }
func onLongPressGestureAction(_ gesture: UILongPressGestureRecognizer) { }
- animations
withAnimation {
self.box.alpha = 1.0
}
withAnimation(.default) {
self.box.alpha = 1.0
}
withAnimation(.default(duration: 0.5)) {
self.box.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
}
withAnimation(.default(duration: 0.5)) {
self.box.alpha = 1.0
} completion: { _ in
self.box.removeFromSuperview()
}
withAnimation(.default(duration: 0.5), completion: { _ in
self.box.alpha = 0.0
}) {
self.box.removeFromSuperview()
}
withAnimation(.easeInOut) {
self.box.centerYConstraint.constant += 100
self.box.layoutIfNeeded()
}
withAnimation(.easeInOut(duration: 0.5, delay: 0.5, refreshAllViews: true)) {// refreshAllViews default is False
self.box.centerYConstraint.constant += 100
self.box.layoutIfNeeded()
}
withAnimation(.easeIn) {
self.box.centerYConstraint.constant += 100
self.box.layoutIfNeeded()
}
withAnimation(.easeOut) {
self.box.alpha = 1.0
}
withAnimation(.linear) {
self.box.alpha = 1.0
}
withAnimation(.delay(0.5, animation: .default)) {
self.box.backgroundColor = .green
}
withAnimation(.spring(duration: 0.5, dampingRatio: 0.5, initialVelocity: 0.5)) {
self.box.centerYConstraint.constant += 100
self.box.layoutIfNeeded()
}
withAnimation(.repeatCount(3, autoreverses: true, animation: .default)) {
self.box.transform = CGAffineTransform(rotationAngle: .pi/4)
}
withAnimation(.repeatForever(autoreverses: true, animation: .default)) {
self.box.transform = CGAffineTransform(rotationAngle: .pi/4)
}
UIStackView Build
let stackView = UIStackView()
.axis(.vertical)
.spacing(10)
.alignment(.center)
.distribution(.fillEqually)
.padding()// all padding default 16
.padding(.all)// default 16
.padding(.all, 20)
.padding(.top)// default 16
.padding(.bottom, 20)
.padding(.left, 20)
.padding(.right, 20)
.padding(.horizontal)// default 16
.padding(.vertical, 30)
.separator(color: .red, size: CGSize(width: 20, height: 2))
UITextView Build
let textView = UITextView()
.font(.regular(16))
.textColor(.black)
.foregroundColor(.black)
.alignment(.left)
.keyboardType(.numberPad)
.text("input text")
.placeholder("placeholder", color: .placeholderText)
.editable(true)
.maxLength(50)
.padding()
.padding(.horizontal, 10)
.padding(.vertical, 10)
.onTextChange(onTextChangeAction)
.onTextChange(onTextViewChangeAction)
.onBeginEditing(onBeginEditingAction)
.onEndEditing(onEndEditingAction)
func onTextChangeAction(_ text: String) {}
func onTextViewChangeAction(_ textView: UITextView) {}
func onBeginEditingAction(_ textView: UITextView) {}
func onEndEditingAction(_ textView: UITextView) {}
UITextField Build
let textField = UITextField()
.font(.regular(16))
.textColor(.black)
.foregroundColor(.black)
.alignment(.left)
.keyboardType(.numberPad)
.text("input text")
.placeholder("placeholder", color: .placeholderText)
.padding()
.padding(.horizontal, 10)
.padding(.vertical, 10)
.maxLength(10)
.onTextChange(onTextChangeAction)
.onTextChange(onTextViewChangeAction)
.onBeginEditing(onBeginEditingAction)
.onEndEditing(onEndEditingAction)
func onTextChangeAction(_ text: String) {}
func onTextViewChangeAction(_ textView: UITextView) {}
func onBeginEditingAction(_ textView: UITextView) {}
func onEndEditingAction(_ textView: UITextView) {}
UILabel Build
let label = UILabel()
.font(.regular(16))
.textColor(.black)
.foregroundColor(.black)
.alignment(.left)
.text("input text")
.lineSpacing(20, wordSpacing: 2)
UIControl Build
let contorl = UIControl()
.onAction { print("click") }
.onAction(for: .touchUpInside, action: { print("click") })
.onAction(self, action: #selector(click))
UIButton Build
let button = UIButton()
.image(UIImage(named: "image"), state: .normal)
.imageName("local_imageName", state: .selected)
.backgroundImage(UIImage.gradient(colors: [.red, .green], direction: .leftToRight, size: CGSize(width: 100, height: 100)))
.backgroundImageName("local_imageName", state: .normal)
.cornerRadius(20)
.onAction{ print("action") }