构建可复用的 SwiftUI 组件库
发布: (2025年12月2日 GMT+8 08:37)
4 min read
原文: Dev.to
Source: Dev.to
SwiftUI 让 构建 UI 变得轻而易举——但要打造在整个应用中保持一致的 可复用组件 则是另一番挑战。
随着应用的增长,UI 重复出现会成为真正的问题:
- 重复的按钮样式
- 不一致的卡片形状
- 重复的文本修饰符
- 复制‑粘贴的阴影
- 同一布局的多个版本
组件库 能解决这些问题。
今天你将学习如何构建一个现代、可扩展、符合 Apple 风格的 SwiftUI 组件库,内容包括:
- 按钮
- 卡片
- 文本框
- 浮动面板
- 标签(Chip)
- 设计令牌(颜色、圆角、阴影)
- 可复用的修饰符
- 一致的样式
这正是我在真实生产应用中使用的完整结构。让我们一起动手吧 🚀
1. 从 Design 文件夹开始
Design/
├── Colors.swift
├── Radii.swift
├── Shadows.swift
└── Typography.swift
Colors.swift
enum AppColor {
static let primary = Color.blue
static let background = Color(.systemBackground)
static let glassStroke = Color.white.opacity(0.25)
}
Radii.swift
enum AppRadius {
static let small: CGFloat = 10
static let medium: CGFloat = 16
static let large: CGFloat = 22
}
Shadows.swift
enum AppShadow {
static let card = Color.black.opacity(0.18)
static let glow = Color.blue.opacity(0.3)
}
Typography.swift
enum AppFont {
static let title = Font.system(.title3, design: .rounded).bold()
static let body = Font.system(.body, design: .rounded)
}
一处定义 → 全局一致。
2. 可复用的按钮样式
PrimaryButton
struct PrimaryButton: View {
let title: String
let action: () -> Void
var body: some View {
Button(action: action) {
Text(title)
.font(AppFont.body.bold())
.padding(.horizontal, 28)
.padding(.vertical, 14)
.background(AppColor.primary)
.foregroundColor(.white)
.clipShape(RoundedRectangle(cornerRadius: AppRadius.medium, style: .continuous))
.shadow(color: AppShadow.card, radius: 16, y: 8)
}
}
}
使用方式
PrimaryButton(title: "Continue") {
print("Pressed")
}
3. 玻璃卡片组件(可复用)
struct GlassCard: View {
@ViewBuilder let content: () -> Content
var body: some View {
content()
.padding(20)
.background(.ultraThinMaterial)
.clipShape(RoundedRectangle(cornerRadius: AppRadius.large, style: .continuous))
.overlay(
RoundedRectangle(cornerRadius: AppRadius.large, style: .continuous)
.stroke(AppColor.glassStroke, lineWidth: 1)
)
.shadow(color: AppShadow.card, radius: 24, y: 12)
}
}
使用方式
GlassCard {
VStack(alignment: .leading) {
Text("Glass Card")
.font(AppFont.title)
Text("Reusable glassmorphic component.")
.foregroundColor(.secondary)
}
}
4. 文本框组件(现代、简洁)
struct AppTextField: View {
var title: String
@Binding var text: String
var body: some View {
TextField(title, text: $text)
.padding(.horizontal, 14)
.padding(.vertical, 12)
.background(.ultraThinMaterial)
.clipShape(RoundedRectangle(cornerRadius: AppRadius.medium))
.overlay(
RoundedRectangle(cornerRadius: AppRadius.medium)
.stroke(AppColor.glassStroke)
)
.shadow(color: AppShadow.card.opacity(0.25), radius: 12, y: 6)
}
}
使用方式
@State private var name = ""
AppTextField(title: "Name", text: $name)
5. Chip / Tag
struct Chip: View {
let label: String
let icon: String?
var body: some View {
HStack(spacing: 6) {
if let icon { Image(systemName: icon) }
Text(label)
}
.font(.caption)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(.ultraThinMaterial)
.clipShape(Capsule())
.overlay(Capsule().stroke(AppColor.glassStroke))
}
}
示例
HStack {
Chip(label: "SwiftUI", icon: "swift")
Chip(label: "Design", icon: "paintbrush")
}
6. 浮动面板(可复用的底部弹出顶部区域)
struct FloatingPanel: View {
@ViewBuilder let content: () -> Content
var body: some View {
VStack(spacing: 0) {
Capsule()
.fill(AppColor.glassStroke)
.frame(width: 40, height: 6)
.padding(.top, 10)
content()
.padding()
}
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: AppRadius.large, style: .continuous))
.shadow(color: .black.opacity(0.25), radius: 30, y: 14)
}
}
7. 可复用的修饰符(强大工具!)
struct CardPadding: ViewModifier {
func body(content: Content) -> some View {
content
.padding(20)
.clipShape(RoundedRectangle(cornerRadius: AppRadius.large))
}
}
extension View {
func cardPadding() -> some View {
modifier(CardPadding())
}
}
修饰符让你的视图保持简洁且具声明式风格。
8. 推荐的文件夹结构
Design/
│ Colors.swift
│ Radii.swift
│ Shadows.swift
│ Typography.swift
│
Components/
│ Buttons/
│ Cards/
│ TextFields/
│ Panels/
│ Chips/
│ Modifiers/
一切清晰,一切可扩展。
结束语
SwiftUI 组件库能为你带来:
- 一致的设计
- 更快的迭代速度
- 可复用的构建块
- 可扩展的架构
- 更容易的团队上手
- 更精致的 UI
这就是从“构建界面” → “构建系统”的转变方式。