SwiftUI中如何使用Button控件实现新增VStack视图的功能
问题原因
你写的代码存在两个核心问题:
- SwiftUI的
Button的action闭包是用来执行业务逻辑的,不能直接返回视图完成渲染,所有要显示的视图都必须写在body的视图树内 - SwiftUI是状态驱动的视图框架,视图的增减必须通过状态变量的变化来触发
正确实现方案
以下代码完全适配iOS 14 + Xcode 12的运行环境,通过状态变量控制动态视图的生成:
import SwiftUI struct ContentView: View { // 状态变量作为动态视图的数据源,每一项对应一个VStack的内容 @State private var textList: [String] = [] var body: some View { // 外层容器统一放置按钮和动态生成的视图 VStack(spacing: 16) { Button(action: { // 点击仅修改数据源,自动触发视图刷新 textList.append("hello") }, label: { Image(systemName: "plus.circle.fill") .foregroundColor(.black) }) // 遍历数据源生成对应数量的VStack ForEach(textList.indices, id: \.self) { index in VStack { Text(textList[index]) } } Spacer() } .padding() } }
可选优化
如果需要给每个VStack绑定更复杂的自定义属性,可以定义遵循Identifiable协议的结构体简化写法:
// 自定义数据结构 struct CustomItem: Identifiable { let id = UUID() let content: String // 可按需添加更多自定义属性 } struct ContentView: View { // 状态变量改为存储自定义结构体 @State private var itemList: [CustomItem] = [] var body: some View { VStack(spacing: 16) { Button(action: { itemList.append(CustomItem(content: "hello")) }, label: { Image(systemName: "plus.circle.fill") .foregroundColor(.black) }) // 不需要手动指定id,写法更简洁 ForEach(itemList) { item in VStack { Text(item.content) } } Spacer() } .padding() } }
内容的提问来源于stack exchange,提问作者SimpsonHuang
相关产品推荐
相关产品推荐

