如何在swiftUI中将文本旁边的颜色添加到列表中?(数据流)

How to Add Color beside text into the list in swiftUI?(Data Flow)

我尝试从用户那里获取(文本和颜色)并将它们添加到 SwiftUI 中的列表中我已经可以传递文本数据但不幸的是对于颜色我不能,而他们应该是一样的,下面是 app.To 作品的图片我们应该为 PreAddTextField 提供 Binding。感谢您的帮助 这是我的代码:

import SwiftUI

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: "", color: .purple)) })
        
        VStack {
            ScrollView {
                ForEach(viewModel.textItemsToAdd, id: \.id) { item in //note this is id: 

\.id and not \.self
                        PreAddTextField(textInTextField: viewModel.bindingForId(id: item.id), colorPickerColor: <#Binding<Color>#>)
                }
                
            }
        }
        .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 SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        AddListView(showAddListView: .constant(false),appState: AppState())
    }
}

struct PreAddTextField: View {


@Binding var textInTextField : String
@Binding var colorPickerColor :  Color

var body: some View {
    HStack {
        TextField("Enter text", text: $textInTextField)
        ColorPicker("", selection: $colorPickerColor)
    }
}
}

struct Buttons: View {
    @Binding var showAddListView : Bool
    var save : () -> Void
    var body: some View {
        VStack {
            HStack(spacing:100) {
                Button(action: {
                        showAddListView = false}) {
                    Text("Cancel")
                }
                Button(action: {
                    showAddListView = false
                    // What should happen here to add Text to List???
                    save()
                }) {
                    Text("Add")
                }
            }
        }
        .offset(y: 70)
    }
}

struct Title: View {

var addItem : () -> Void

var body: some View {
    VStack {
        HStack {
            Text("Add Text to list")
                .font(.title2)
            Spacer()
            Button(action: {
                addItem()
            }) {
                Image(systemName: "plus")
                    .font(.title2)
            }
        }
        .padding()
        Spacer()
    }
}
}

数据模型:

import SwiftUI

struct Text1 : Identifiable , Hashable{
    var id = UUID()
    var text : String
    var color : Color
}

class AppState : ObservableObject {
    @Published var textData : [Text1] = [.init(text: "Item 1", color: .purple),.init(text: "Item 2", color: .purple)]
}

class AddListViewViewModel : ObservableObject {
    @Published var textItemsToAdd : [Text1] = [.init(text: "", color: .purple)] //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 { ![=11=].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: { [=11=].id == id })?.text ?? ""
    } set: { (newValue) in
        self.textItemsToAdd = self.textItemsToAdd.map {
            guard [=11=].id == id else {
                return [=11=]
            }
            return .init(id: id, text: newValue, color: .purple)
        }
    }
}
}

最后:

import SwiftUI

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
                    HStack {
                        Image(systemName: "square")
                            .foregroundColor(text.color)
                        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 ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ListView()
    }
}

您可以为整个 Text1 项创建一个 Binding,而不是仅对 String 使用 Binding

class AddListViewViewModel : ObservableObject {
    @Published var textItemsToAdd : [Text1] = [.init(text: "", color: .purple)]
    
    func saveToAppState(appState: AppState) {
        appState.textData.append(contentsOf: textItemsToAdd.filter { ![=10=].text.isEmpty })
    }
    
    func bindingForId(id: UUID) -> Binding<Text1> { //now returns a Text1
        .init { () -> Text1 in
            self.textItemsToAdd.first(where: { [=10=].id == id }) ?? Text1(text: "", color: .clear)
        } set: { (newValue) in
            self.textItemsToAdd = self.textItemsToAdd.map {
                guard [=10=].id == id else {
                    return [=10=]
                }
                return newValue
            }
        }
    }
}

struct PreAddTextField: View {
    @Binding var item : Text1
    
    var body: some View {
        HStack {
            TextField("Enter text", text: $item.text) //gets the text property of the binding
            ColorPicker("", selection: $item.color) //gets the color property
        }
    }
}

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: "", color: .purple)) })
            VStack {
                ScrollView {
                    ForEach(viewModel.textItemsToAdd, id: \.id) { item in
                        PreAddTextField(item: viewModel.bindingForId(id: item.id)) //parameter is changed here
                    }
                }
            }
            .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)
    }
}