IOS SwiftUI 全组件详解

内容分享7小时前发布
0 0 0

SwiftUI 全组件详解(iOS 端)

SwiftUI 是苹果推出的声明式 UI 框架,覆盖 iOS、macOS、watchOS 等多平台,下面是 iOS 端核心组件的分类详解,包含用法、核心属性和常见场景,基于最新 SwiftUI 5(iOS 18)适配。

一、基础视图组件

基础视图是构建 UI 的最小单元,用于展示文本、图片、图标等核心内容。

1. Text(文本)

作用 :展示静态/动态文本,支持富文本、样式定制。核心属性

  • font(_:) :设置字体( Font.title / Font.system(size:16, weight:.bold) );
  • foregroundStyle(_:) :文本颜色(支持渐变) #iOS;
  • multilineTextAlignment(_:) :对齐方式( .leading / .center / .trailing );
  • lineLimit(_:) :行数限制( nil 表明无限制);
  • truncationMode(_:) :截断方式( .tail / .head / .middle )。

示例

Text("Hello SwiftUI")
    .font(.title)
    .foregroundStyle(LinearGradient(colors: [.red, .blue], startPoint: .leading, endPoint: .trailing))
    .padding()

2. Image(图片)

作用 :展示本地/网络图片,支持缩放、裁剪、渲染模式。核心属性

  • resizable(capInsets:resizingMode:) :自适应尺寸(必加,否则图片按原始尺寸显示);
  • scaledToFit() / scaledToFill() :适配方式(保持比例);
  • clipShape(_:) :裁剪形状( Circle() / RoundedRectangle(cornerRadius:10) );
  • renderingMode(_:) :渲染模式( .original 保留原图, .template 作为模板色);
  • asyncImage(url:) :加载网络图片(iOS 15+)。

示例

// 本地图片
Image("avatar")
    .resizable()
    .scaledToFit()
    .frame(width: 100, height: 100)
    .clipShape(Circle())

// 网络图片 AsyncImage(url: URL(string: "https://example.com/photo.jpg")) { phase in switch phase { case .empty: ProgressView() // 加载中 case .success(let image): image.resizable().scaledToFit() case .failure: Image(systemName: "photo.badge.exclamationmark") // 加载失败 @unknown default: EmptyView() } } .frame(width: 200, height: 200)

3. Image(systemName:)(SF Symbols 图标)

作用 :使用苹果内置的 SF Symbols 图标库,支持自定义颜色/大小。核心属性

  • font(_:) :设置图标大小( Font.system(size:24) );
  • foregroundStyle(_:) :图标颜色;
  • symbolVariant(_:) :图标变体( .fill / .circle / .square );
  • symbolRenderingMode(_:) :渲染模式( .hierarchical / .palette )。

示例

Image(systemName: "heart.fill")
    .font(.system(size: 32))
    .foregroundStyle(.red)
    .symbolVariant(.circle)

4. Label(标签)

作用 :组合图标+文本的复合视图(系统默认排版)。核心属性

  • init(_ title: String, systemImage: String) :快捷创建(文本+SF 图标);
  • labelStyle(_:) :样式( .iconOnly / .titleOnly / .titleAndIcon / .automatic );
  • titleSpacing(_:) :图标与文本间距。

示例

Label("设置", systemImage: "gear")
    .labelStyle(.automatic)
    .labelIconToTitleSpacing(8)
    .foregroundStyle(.gray)

二、容器视图组件

容器视图用于布局和管理多个子视图,是构建复杂 UI 的核心。

1. VStack(垂直栈)

作用 :垂直排列子视图,默认居中对齐。核心属性

  • init(alignment: HorizontalAlignment, spacing: CGFloat?, content:) :对齐方式、子视图间距;
  • spacing :子视图间距(默认系统自适应);
  • alignment :水平对齐( .leading / .center / .trailing / .top 等)。

示例

VStack(alignment: .leading, spacing: 12) {
    Text("标题")
        .font(.headline)
    Text("副标题")
        .font(.subheadline)
        .foregroundStyle(.gray)
}
.padding()

2. HStack(水平栈)

作用 :水平排列子视图,默认居中对齐。核心属性

  • init(alignment: VerticalAlignment, spacing: CGFloat?, content:) :垂直对齐、子视图间距;
  • alignment :垂直对齐( .top / .center / .bottom / .firstTextBaseline 等)。

示例

HStack(alignment: .center, spacing: 8) {
    Image(systemName: "bell")
    Text("消息通知")
    Spacer() // 推挤右侧视图到最右
    Image(systemName: "chevron.right")
        .foregroundStyle(.gray)
}
.padding(.horizontal)

3. ZStack(层级栈)

作用 :重叠排列子视图,默认居中对齐。核心属性

  • init(alignment: Alignment, content:) :对齐方式( .topLeading / .center / .bottomTrailing 等);
  • zIndex(_:) :子视图层级(数值越大越上层)。

示例

ZStack(alignment: .bottomTrailing) {
    Image("background")
        .resizable()
        .scaledToFill()
        .frame(width: 200, height: 200)
    Text("标签")
        .padding(4)
        .background(Color.red)
        .foregroundStyle(.white)
        .cornerRadius(4)
        .padding(8)
}
.clipShape(RoundedRectangle(cornerRadius: 10))

4. List(列表)

作用 :滚动列表,支持单行/分组/可编辑,替代 UIKit 的 UITableView。核心属性

  • listStyle(_:) :列表样式( .plain / .grouped / .insetGrouped / .sidebar );
  • onDelete(perform:) :删除操作(需配合 ForEach );
  • onMove(perform:) :移动操作(需配合 EditButton );
  • selection(_:) :选中项绑定(iOS 14+)。

示例

struct ListDemo: View {
    @State private var items = ["苹果", "香蕉", "橙子"]
    @State private var editing = false

    var body: some View {
        NavigationStack {
            List {
                ForEach(items, id: .self) { item in
                    Text(item)
                }
                .onDelete { indexSet in
                    items.remove(atOffsets: indexSet)
                }
                .onMove { source, destination in
                    items.move(fromOffsets: source, toOffset: destination)
                }
            }
            .listStyle(.insetGrouped)
            .navigationTitle("水果列表")
            .toolbar {
                EditButton() // 编辑按钮
            }
        }
    }
}

5. ScrollView(滚动视图)

作用 :可滚动的容器,支持垂直/水平滚动,无默认单元格复用(区别于 List)。核心属性

  • init(.vertical/.horizontal, showsIndicators: Bool, content:) :滚动方向、是否显示滚动条;
  • scrollIndicators(_:) :滚动条样式( .hidden / .automatic / .visible );
  • scrollDismissesKeyboard(_:) :滚动时关闭键盘( .immediately / .interactively )。

示例

ScrollView(.vertical, showsIndicators: false) {
    VStack(spacing: 20) {
        ForEach(1...20, id: .self) { i in
            Text("滚动项 (i)")
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color.gray.opacity(0.1))
                .cornerRadius(8)
        }
    }
    .padding()
}

6. LazyVStack/LazyHStack(懒加载栈)

作用 :类似 VStack/HStack,但仅渲染可视区域内的子视图,适合长列表(性能优化)。核心属性

  • pinnedViews(_:) :固定视图( .sectionHeaders / .sectionFooters );
  • 其他属性与普通栈一致。

示例

ScrollView {
    LazyVStack(spacing: 10, pinnedViews: .sectionHeaders) {
        Section(header: Text("头部固定").font(.title).background(Color.white)) {
            ForEach(1...100, id: .self) { i in
                Text("懒加载项 (i)")
                    .frame(height: 50)
            }
        }
    }
}

7. Grid(网格)

作用 :二维网格布局(iOS 16+),替代手动嵌套 HStack/VStack。核心组件

  • GridRow :网格行;
  • GridItem :网格列配置( .flexible() / .adaptive(minimum:) / .fixed() );
  • alignment :单元格对齐方式。

示例

Grid(alignment: .center, horizontalSpacing: 8, verticalSpacing: 8) {
    GridRow {
        Text("1")
            .frame(maxWidth: .infinity)
            .background(Color.gray.opacity(0.1))
        Text("2")
            .frame(maxWidth: .infinity)
            .background(Color.gray.opacity(0.1))
    }
    GridRow {
        Text("3")
            .frame(maxWidth: .infinity)
            .background(Color.gray.opacity(0.1))
        Text("4")
            .frame(maxWidth: .infinity)
            .background(Color.gray.opacity(0.1))
    }
}
.padding()

8. Group(分组)

作用 :分组子视图,无视觉效果,仅用于拆分代码或突破 10 个子视图限制。示例

VStack {
    Group {
        Text("1")
        Text("2")
        Text("3")
    }
    Group {
        Text("4")
        Text("5")
    }
}

三、交互控件组件

用于响应用户操作(点击、输入、选择等)的交互型组件。

1. Button(按钮)

作用 :响应点击操作,支持自定义样式。核心属性

  • init(action: @escaping () -> Void, label: () -> Label) :点击事件、按钮内容;
  • buttonStyle(_:) :样式( .plain / .bordered / .borderedProminent / .borderless );
  • tint(_:) :按钮主色调;
  • disabled(_:) :是否禁用。

示例

Button(action: {
    print("按钮点击")
}) {
    HStack {
        Image(systemName: "paperplane")
        Text("提交")
    }
}
.buttonStyle(.borderedProminent)
.tint(.blue)
.disabled(false)
.padding()

2. Toggle(开关)

作用 :布尔值切换控件(类似 UISwitch)。核心属性

  • init(isOn: Binding<Bool>, label:) :绑定布尔值、标签;
  • toggleStyle(_:) :样式( .switch / .button / .checkbox );
  • tint(_:) :开启状态颜色。

示例

struct ToggleDemo: View {
    @State private var isOn = false

    var body: some View {
        Toggle(isOn: $isOn) {
            Text("开启通知")
        }
        .toggleStyle(.switch)
        .tint(.green)
        .padding()
    }
}

3. TextField(单行输入框)

作用 :单行文本输入,支持键盘类型、占位符等。核心属性

  • init(_ prompt: String, text: Binding<String>) :占位符、绑定文本;
  • keyboardType(_:) :键盘类型( .numberPad / .emailAddress / .default );
  • autocapitalization(_:) :自动大写( .none / .words );
  • disableAutocorrection(_:) :禁用自动纠错;
  • onCommit(perform:) :回车触发事件。

示例

struct TextFieldDemo: View {
    @State private var text = ""

    var body: some View {
        TextField("请输入用户名", text: $text)
            .keyboardType(.default)
            .autocapitalization(.none)
            .disableAutocorrection(true)
            .padding()
            .background(Color.gray.opacity(0.1))
            .cornerRadius(8)
            .padding(.horizontal)
    }
}

4. TextEditor(多行文本编辑器)

作用 :多行文本输入(类似 UITextView)。核心属性

  • init(text: Binding<String>) :绑定文本;
  • foregroundStyle(_:) :文本颜色;
  • font(_:) :字体;
  • scrollContentBackground(_:) :是否显示滚动背景( .hidden 可去除默认白色背景)。

示例

struct TextEditorDemo: View {
    @State private var text = ""

    var body: some View {
        TextEditor(text: $text)
            .font(.body)
            .foregroundStyle(.black)
            .scrollContentBackground(.hidden)
            .background(Color.gray.opacity(0.1))
            .frame(height: 150)
            .padding()
    }
}

5. Slider(滑块)

作用 :数值选择滑块(范围值)。核心属性

  • init(value: Binding<Double>, in range: ClosedRange<Double>, step: Double) :绑定值、范围、步长;
  • tint(_:) :滑块进度颜色;
  • onChange(of: value) { newValue in } :值变化监听。

示例

struct SliderDemo: View {
    @State private var progress = 0.0

    var body: some View {
        VStack {
            Slider(value: $progress, in: 0...100, step: 1)
                .tint(.orange)
                .padding()
            Text("进度:(Int(progress))%")
        }
    }
}

6. Picker(选择器)

作用 :下拉/滚轮选择器,支持多类型数据源。核心属性

  • init(selection: Binding<Value>, label: Label, content:) :选中值绑定、标签;
  • pickerStyle(_:) :样式( .menu / .wheel / .segmented / .inline );
  • ForEach :数据源遍历。

示例

struct PickerDemo: View {
    @State private var selectedFruit = "苹果"
    let fruits = ["苹果", "香蕉", "橙子", "葡萄"]

    var body: some View {
        Picker(selection: $selectedFruit, label: Text("选择水果")) {
            ForEach(fruits, id: .self) {
                Text($0)
            }
        }
        .pickerStyle(.menu) // 下拉菜单样式
        .padding()
    }
}

7. DatePicker(日期选择器)

作用 :日期/时间选择器(类似 UIDatePicker)。核心属性

  • init(_ label: String, selection: Binding<Date>, displayedComponents:) :标签、绑定日期、显示组件( .date / .time / .dateAndTime );
  • datePickerStyle(_:) :样式( .compact / .wheel / .graphical );
  • range(_:) :可选日期范围。

示例

struct DatePickerDemo: View {
    @State private var selectedDate = Date()

    var body: some View {
        DatePicker("选择日期", selection: $selectedDate, displayedComponents: .date)
            .datePickerStyle(.compact)
            .padding()
    }
}

8. Stepper(步进器)

作用 :增减数值的控件(+/- 按钮)。核心属性

  • init(_ label: String, value: Binding<Value>, in range: ClosedRange<Value>, step: Value) :标签、绑定值、范围、步长;
  • onIncrement(perform:) :增加触发事件;
  • onDecrement(perform:) :减少触发事件。

示例

struct StepperDemo: View {
    @State private var count = 0

    var body: some View {
        Stepper("数量:(count)", value: $count, in: 0...10, step: 1)
            .padding()
    }
}

四、导航与页面组件

用于页面跳转、导航栏管理、模态弹窗等场景。

1. NavigationStack(导航栈,iOS 16+)

作用 :替代旧版 NavigationView ,实现页面层级导航。核心属性

  • init(path: Binding<NavigationPath>, root:) :导航路径绑定(支持任意可哈希类型);
  • navigationTitle(_:) :导航栏标题;
  • navigationBarTitleDisplayMode(_:) :标题显示模式( .large / .inline / .automatic );
  • toolbar(content:) :导航栏工具栏(按钮、菜单);
  • navigationDestination(for:destination:) :目标页面映射。

示例

struct NavigationDemo: View {
    @State private var path = NavigationPath()
    let fruits = ["苹果", "香蕉", "橙子"]

    var body: some View {
        NavigationStack(path: $path) {
            List(fruits, id: .self) { fruit in
                NavigationLink(value: fruit) {
                    Text(fruit)
                }
            }
            .navigationTitle("水果列表")
            .navigationDestination(for: String.self) { fruit in
                Text("你选择了:(fruit)")
                    .navigationTitle(fruit)
            }
            .toolbar {
                Button("返回首页") {
                    path.removeLast(path.count)
                }
            }
        }
    }
}

2. Sheet(模态弹窗)

作用 :弹出模态视图(从底部滑入)。核心属性

  • sheet(isPresented: Binding<Bool>, onDismiss: (() -> Void)?, content:) :显示状态绑定、关闭回调、弹窗内容;
  • presentationDetents(_:) :弹窗高度( .height(200) / .medium / .large ,iOS 16+);
  • presentationDragIndicator(_:) :拖拽指示器( .visible / .hidden ,iOS 16+)。

示例

struct SheetDemo: View {
    @State private var showSheet = false

    var body: some View {
        Button("打开弹窗") {
            showSheet = true
        }
        .sheet(isPresented: $showSheet) {
            Text("模态弹窗内容")
                .presentationDetents([.medium, .large])
                .presentationDragIndicator(.visible)
        }
    }
}

3. Alert(警告弹窗)

作用 :系统样式的警告弹窗(含标题、按钮)。核心属性

  • alert(_: isPresented: actions: message:) :标题、显示状态、按钮组、消息内容;
  • ButtonRole :按钮角色( .cancel / .destructive / .none )。

示例

struct AlertDemo: View {
    @State private var showAlert = false

    var body: some View {
        Button("显示警告") {
            showAlert = true
        }
        .alert("提示", isPresented: $showAlert) {
            Button("撤销", role: .cancel) {}
            Button("确认", role: .none) {}
        } message: {
            Text("确定要执行此操作吗?")
        }
    }
}

4. Popover(弹出框,iOS 14+)

作用 :从指定位置弹出的气泡视图。核心属性

  • popover(isPresented: attachmentAnchor: arrowEdge: content:) :显示状态、锚点、箭头方向、内容。

示例

struct PopoverDemo: View {
    @State private var showPopover = false

    var body: some View {
        Button("弹出菜单") {
            showPopover = true
        }
        .popover(isPresented: $showPopover, attachmentAnchor: .point(.topTrailing), arrowEdge: .top) {
            VStack {
                Text("选项1")
                Text("选项2")
                Text("选项3")
            }
            .padding()
            .frame(width: 150)
        }
    }
}

五、视觉装饰组件

用于增强 UI 视觉效果的装饰性组件。

1. Divider(分割线)

作用 :水平分割线,用于分隔视图。核心属性

  • foregroundStyle(_:) :分割线颜色;
  • frame(height:) :分割线高度。

示例

VStack {
    Text("上部分")
    Divider()
        .foregroundStyle(.gray.opacity(0.3))
        .frame(height: 1)
    Text("下部分")
}
.padding()

2. Spacer(空白填充)

作用 :占据剩余空间,用于推挤子视图到指定位置。核心属性

  • minLength(_:) :最小长度(默认 0)。

示例

HStack {
    Text("左侧")
    Spacer(minLength: 20)
    Text("右侧")
}
.padding()

3. Color(颜色视图)

作用 :纯色背景/装饰,可作为视图使用。核心属性

  • opacity(_:) :透明度;
  • gradient(_:) :渐变(LinearGradient/RadialGradient/AngularGradient);
  • frame() :尺寸(默认填充父视图)。

示例

Color.blue
    .opacity(0.5)
    .frame(height: 100)
    .cornerRadius(10)
    .padding()

4. RoundedRectangle/Circle/Capsule(形状视图)

作用 :基础形状,用于背景、裁剪、装饰。核心属性

  • fill(_:) :填充颜色/渐变;
  • stroke(_:lineWidth:) :描边;
  • cornerRadius(_:) (仅 RoundedRectangle):圆角。

示例

RoundedRectangle(cornerRadius: 12)
    .fill(LinearGradient(colors: [.purple, .pink], startPoint: .leading, endPoint: .trailing))
    .stroke(Color.white, lineWidth: 2)
    .frame(width: 200, height: 100)

六、高级组件(iOS 14+)

1. ProgressView(进度条)

作用 :展示加载进度(确定/不确定)。核心属性

  • init(value: Binding<Double>?, total: Double = 1.0) :进度值、总进度;
  • progressViewStyle(_:) :样式( .linear / .circular / .automatic );
  • tint(_:) :进度颜色。

示例

struct ProgressViewDemo: View {
    @State private var progress = 0.5

    var body: some View {
        VStack {
            // 确定进度
            ProgressView(value: progress, total: 1.0)
                .progressViewStyle(.linear)
                .tint(.blue)
                .padding()
            // 不确定进度(加载中)
            ProgressView()
                .progressViewStyle(.circular)
                .tint(.orange)
        }
    }
}

2. Menu(菜单)

作用 :下拉菜单(点击展开选项)。核心属性

  • init(content: label:) :菜单内容、触发标签;
  • menuStyle(_:) :样式( .borderlessButton / .contextMenu );
  • Button(role:) :菜单选项(支持撤销/销毁角色)。

示例

Menu {
    Button("编辑", action: {})
    Button("删除", role: .destructive, action: {})
    Button("分享", action: {})
    Divider()
    Button("撤销", role: .cancel, action: {})
} label: {
    Label("更多操作", systemImage: "ellipsis.circle")
}

3. TabView(标签页)

作用 :底部/顶部标签页切换(类似 UITabBarController)。核心属性

  • tabViewStyle(_:) :样式( .page / .tabBar );
  • tabItem { Label(…) } :标签项内容;
  • tag(_:) :标签标识(配合选中绑定);
  • selection(_:) :选中标签绑定。

示例

struct TabViewDemo: View {
    @State private var selectedTab = 0

    var body: some View {
        TabView(selection: $selectedTab) {
            Text("首页")
                .tabItem {
                    Label("首页", systemImage: "house")
                }
                .tag(0)
            Text("消息")
                .tabItem {
                    Label("消息", systemImage: "bell")
                }
                .tag(1)
            Text("我的")
                .tabItem {
                    Label("我的", systemImage: "person")
                }
                .tag(2)
        }
        .tint(.blue)
    }
}

七、关键注意事项

  1. 版本适配 :部分组件(如 NavigationStack 、 Grid )仅支持 iOS 16+,低版本需用 NavigationView 等兼容方案;
  2. 性能优化 :长列表优先用 List / LazyVStack ,避免普通 VStack 导致的卡顿;
  3. 状态管理 :所有交互组件需配合 @State / @Binding / @ObservedObject 等状态属性;
  4. 样式定制 :可通过 ViewModifier 封装自定义样式,减少重复代码;
  5. 多平台兼容 :部分组件(如 SidebarListStyle )仅在 iPad/macOS 生效,iOS 需适配。

以上覆盖了 SwiftUI 核心组件,实际开发中可结合苹果官方文档( SwiftUI 官方文档 )和 SF Symbols 库扩展使用。

© 版权声明

相关文章

暂无评论

none
暂无评论...