如何在SwiftUI中将多个文本添加到列表中?(数据流)
我正试图通过swiftUI构建一个演示应用程序,从用户那里获取多个文本,并将它们添加到下面的列表中,每次用户按下加号按钮时,都会出现应用程序的图像。AddListView会显示给用户,用户可以在列表中添加多个文本。我无法通过新的switUI数据流将它们添加到列表中我不知道如何传递数据(我评论更多信息)如何在SwiftUI中将多个文本添加到列表中?(数据流),swiftui,swiftui-list,Swiftui,Swiftui List,我正试图通过swiftUI构建一个演示应用程序,从用户那里获取多个文本,并将它们添加到下面的列表中,每次用户按下加号按钮时,都会出现应用程序的图像。AddListView会显示给用户,用户可以在列表中添加多个文本。我无法通过新的switUI数据流将它们添加到列表中我不知道如何传递数据(我评论更多信息) 谢谢由于问题的多个项目部分,这就变得不那么琐碎了。但是,结合使用observateObjects和回调函数,这是完全可行的。请查看代码中的内联注释,以了解有关发生了什么的解释: struct Te
谢谢由于问题的多个项目部分,这就变得不那么琐碎了。但是,结合使用
observateObject
s和回调函数,这是完全可行的。请查看代码中的内联注释,以了解有关发生了什么的解释:
struct Text1 : Identifiable , Hashable{
var id = UUID()
var text : String
}
//Store the items in an ObservableObject instead of just in @State
class AppState : ObservableObject {
@Published var textData : [Text1] = [.init(text: "Item 1"),.init(text: "Item 2")]
}
//This view model stores data about all of the new items that are going to be added
class AddListViewViewModel : ObservableObject {
@Published var textItemsToAdd : [Text1] = [.init(text: "")] //start with one empty item
//save all of the new items -- don't save anything that is empty
func saveToAppState(appState: AppState) {
appState.textData.append(contentsOf: textItemsToAdd.filter { !$0.text.isEmpty })
}
//these Bindings get used for the TextFields -- they're attached to the item IDs
func bindingForId(id: UUID) -> Binding<String> {
.init { () -> String in
self.textItemsToAdd.first(where: { $0.id == id })?.text ?? ""
} set: { (newValue) in
self.textItemsToAdd = self.textItemsToAdd.map {
guard $0.id == id else {
return $0
}
return .init(id: id, text: newValue)
}
}
}
}
struct AddListView: View {
@Binding var showAddListView : Bool
@ObservedObject var appState : AppState
@StateObject private var viewModel = AddListViewViewModel()
var body: some View {
ZStack {
Title(addItem: { viewModel.textItemsToAdd.append(.init(text: "")) })
VStack {
ScrollView {
ForEach(viewModel.textItemsToAdd, id: \.id) { item in //note this is id: \.id and not \.self
PreAddTextField(textInTextField: viewModel.bindingForId(id: item.id))
}
}
}
.padding()
.offset(y: 40)
Buttons(showAddListView: $showAddListView, save: {
viewModel.saveToAppState(appState: appState)
})
}
.frame(width: 300, height: 200)
.background(Color.white)
.shadow(color: Color.black.opacity(0.3), radius: 10, x: 0, y: 10)
}
}
struct PreAddTextField: View {
@Binding var textInTextField : String //this takes a binding to the view model now
var body: some View {
VStack {
TextField("Enter text", text: $textInTextField)
}
}
}
struct Buttons: View {
@Binding var showAddListView : Bool
var save : () -> Void //callback function for what happens when "Add" gets pressed
var body: some View {
VStack {
HStack(spacing:100) {
Button(action: {
showAddListView = false}) {
Text("Cancel")
}
Button(action: {
showAddListView = false
save()
}) {
Text("Add")
}
}
}
.offset(y: 70)
}
}
struct Title: View {
var addItem : () -> Void //callback function for what happens when the plus button is hit
var body: some View {
VStack {
HStack {
Text("Add Text to list")
.font(.title2)
Spacer()
Button(action: {
addItem()
}) {
Image(systemName: "plus")
.font(.title2)
}
}
.padding()
Spacer()
}
}
}
struct ListView: View {
@StateObject var appState = AppState() //store the AppState here
@State private var showAddListView = false
var body: some View {
NavigationView {
VStack {
ZStack {
List(appState.textData, id : \.self){ text in
Text(text.text)
}
if showAddListView {
AddListView(showAddListView: $showAddListView, appState: appState)
.offset(y:-100)
}
}
}
.navigationTitle("List")
.navigationBarItems(trailing:
Button(action: {showAddListView = true}) {
Image(systemName: "plus")
.font(.title2)
}
)
}
}
}
struct Text1:可识别、可散列{
var id=UUID()
变量文本:字符串
}
//将项目存储在ObserveObject中,而不是仅存储在@State中
类AppState:ObservableObject{
@已发布的变量textData:[Text1]=[.init(文本:“项目1”),.init(文本:“项目2”)]
}
//此视图模型存储有关将要添加的所有新项的数据
类AddListViewModel:ObserveObject{
@已发布的变量textItemsToAdd:[Text1]=[.init(文本:“”)]//从一个空项开始
//保存所有新项--不要保存任何空项
func saveToAppState(appState:appState){
appState.textData.append(contentsOf:textItemsToAdd.filter{!$0.text.isEmpty})
}
//这些绑定用于文本字段——它们附加到项目ID
func bindingForId(id:UUID)->Binding{
.init{()->中的字符串
self.textItemsToAdd.first(其中:{$0.id==id})?.text??“
}集合:{(newValue)在
self.textItemsToAdd=self.textItemsToAdd.map{
guard$0.id==id else{
返回$0
}
return.init(id:id,text:newValue)
}
}
}
}
结构AddListView:视图{
@绑定变量showAddListView:Bool
@ObservedObject变量appState:appState
@StateObject私有变量viewModel=addListViewModel()
var body:一些观点{
ZStack{
标题(addItem:{viewModel.textItemsToAdd.append(.init(文本:))})
VStack{
滚动视图{
ForEach(viewModel.textItemsToAdd,id:\.id){item in//注意这是id:\.id而不是\.self
PreAddTextField(textInTextField:viewModel.bindingForId(id:item.id))
}
}
}
.padding()
.偏移量(y:40)
按钮(showAddListView:$showAddListView,保存:{
viewModel.saveToAppState(appState:appState)
})
}
.框架(宽:300,高:200)
.背景(颜色.白色)
阴影(颜色:颜色。黑色。不透明度(0.3),半径:10,x:0,y:10)
}
}
结构PreAddTextField:视图{
@Binding var textinextfield:String//现在将绑定到视图模型
var body:一些观点{
VStack{
TextField(“输入文本”,text:$textInTextField)
}
}
}
结构按钮:视图{
@绑定变量showAddListView:Bool
var save:()->Void//回调函数,用于在按下“Add”时发生的情况
var body:一些观点{
VStack{
HStack(间距:100){
按钮(操作:{
showAddListView=false}){
文本(“取消”)
}
按钮(操作:{
showAddListView=false
保存()
}) {
文本(“添加”)
}
}
}
.偏移量(y:70)
}
}
结构标题:视图{
var addItem:()->Void//回调函数,用于在按下加号按钮时发生的情况
var body:一些观点{
VStack{
HStack{
文本(“将文本添加到列表”)
.font(.title2)
垫片()
按钮(操作:{
附加项()
}) {
图像(系统名称:“plus”)
.font(.title2)
}
}
.padding()
垫片()
}
}
}
结构列表视图:视图{
@StateObject var appState=appState()//将appState存储在此处
@状态私有变量showAddListView=false
var body:一些观点{
导航视图{
VStack{
ZStack{
列表(appState.textData,id:\.self){text in
Text(Text.Text)
}
如果显示AddListView{
AddListView(showAddListView:$showAddListView,appState:appState)
.偏移量(y:-100)
}
}
}
.navigationTitle(“列表”)
.navigationBarItems(尾部:
按钮(操作:{showAddListView=true}){
图像(系统名称:“plus”)
.font(.title2)
}
)
}
}
}
您的Text1
数组在哪里?您的AddListView
有点混乱。它有一个ForEach
——你打算一次添加多个项目吗?它在名为textDataYes的数据模型中,你是对的,我想用户可以添加多个textfield,然后一次将它们添加到列表中。非常感谢,我真的很感激。我不知道如何感谢你