ios - 如何从结构 View 数组中提取状态? SwiftUI

标签 ios swift swiftui state

我在从 SwiftUI 结构数组中获取状态时遇到问题。

我有一个包含 topText 和 bottomText 的卡片结构。我有另一个结构,它是输入组件(例如卡片)的表单。我将这些卡片存储在一个数组中,随着单击 + 按钮越来越多。在父 View 中,我对该数组有一个 foreach,因此它们可以动态呈现。

我在尝试从这些结构中提取状态值时遇到问题。这些卡片包含 topText 和 bottomText 的状态。当在父数组(存在卡片数组的位置)中单击保存按钮时,它会遍历卡片数组,并通过 get 方法打印它们的状态。但是,它不会打印这些卡片的当前状态。它打印一个空白字符串。我相信这种情况正在发生,因为当我附加结构时,它只是复制了一个死结构,而不是真正的有状态结构。

我的假设是否正确?或者这是 swiftUI 中的错误?有没有人对正确的方法有任何想法?我只想在单击按钮时从卡片中获取输入。但它需要是动态的,因为用户可以多次单击 + 按钮并继续制作更多卡片。

这是卡片结构的代码:

struct memeCard: View, Identifiable{
    @State private var topText = ""
    @State private var bottomText = ""

    let id = UUID()

    //  TODO: figure out how to make text wrap so it doesn't go on one line forever.

    var body: some View{
        VStack(spacing: 30){
            TextField("Top text...", text: $topText).multilineTextAlignment(.center)
            Divider()
            TextField("Bottom text...", text: $bottomText)
        }
        .frame(width: 300, height: 350, alignment: .center).multilineTextAlignment(.center)
        .background(Color.white)
        .cornerRadius(20)
        .shadow(color: Color.gray, radius: 4, x: 4, y: 4)
    }

    func getBottomText() -> String{
        return self.bottomText
    }

    func getTopText() -> String{
        return self.topText
    }
}


这是父 View :

struct CreateMemePage: View {
    @Environment(\.presentationMode) var presentation

    let realm = try! Realm()
    @State private var sectionInput = ""
    @State private var memeTitleInput = ""
    @State private var offsetValue: CGFloat = 0.0
    @State private var createCards: [memeCard] = [memeCard()]

    var body: some View {

NavigationView{
            VStack(spacing: 30){
                ScrollView{
                    TextField("Section...", text: $sectionInput)
                        .multilineTextAlignment(.center)
                        .frame(width: 350, height: 75, alignment: .center)
                        .background(Color.white)
                        .cornerRadius(15)
                        .shadow(color: Color.gray, radius: 4, x: 4, y: 4)

                    TextField("Meme Title...", text: $memeTitleInput)
                        .multilineTextAlignment(.center)
                        .frame(width: 350, height: 75, alignment: .center)
                        .background(Color.white)
                        .cornerRadius(15)
                        .shadow(color: Color.gray, radius: 4, x: 4, y: 4)


                    ForEach(0..<self.createCards.count, id: \.self){ item in
                        self.createCards[item].padding()
                    }

                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
                }

                Button(action: {
                    self.createCards.append(memeCard())
                }) {
                    Image(systemName: "plus")
                        .accentColor(Color.white)
                        .frame(width: 50, height: 50, alignment: .center)
                        .background(LinearGradient(gradient: Gradient(colors: [ .red, .purple]), startPoint: .top, endPoint: .trailing))
                        .cornerRadius(60)
                        .shadow(color: Color.gray, radius: 2, x: 3, y: 3)
                }
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
            .keyboardSensible($offsetValue)

            .navigationBarTitle("Create meme")
            .navigationBarItems(trailing:
                Button(action: {

                 for item in createCards{
                     print(item.getBottomText())
                     print(item.getTopText())
              }
                }){
                    Text("Save")
                }
            )        }

    }

}

最佳答案

你需要知道如何使用ObservableObject , @ObservedObject , @State , 和 @Binding .

但为简单起见,让我们看看我们如何制作您的 memeCard功能起作用。

创建模型

class Model: ObservableObject {
    var topText: String = ""
    var bottomText: String = ""

    init(top: String, bottom: String) {
        self.topText = top
        self.bottomText = bottom
    }
}

memeCard 中使用模型实例看法。
struct memeCard: View, Identifiable{
    @ObservedObject var model = Model(top: "", bottom: "")

    let id = UUID()
    ...

接下来,我们绑定(bind)model textFields 的实例。
VStack(spacing: 30){
    TextField("Top text...", text: self.$model.topText).multilineTextAlignment(.center)
    Divider()
    TextField("Bottom text...", text: self.$model.bottomText)
}

然后我们可以使用现有的顶部和底部函数从模型类中提取数据,如下所示:
func getBottomText() -> String{
    print("BOTTOM: \(self.model.bottomText)")
    return self.model.bottomText
}

func getTopText() -> String{
    print("TOP: \(self.model.topText)")
    return self.model.topText
}

瞧!现在应该可以了。
这个答案来自另一个问题https://stackoverflow.com/a/57623488/3231194
应该能帮到你,写的很全面。

关于ios - 如何从结构 View 数组中提取状态? SwiftUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60612565/

相关文章:

ios - React Native iOS 部署错误

ios - 如何在 iOS swift 中从 Firebase 远程配置获取整数值?

swift - keyPathsForValuesAffecting 与 NSManagedObject

objective-c - 在 Swift 中使用轻量级泛型实现 Objective-C 方法

swift - ARSCNView 以 120 fps 呈现其内容(但我需要 30 fps)

qr-code - 使用 SwiftUI 生成二维码显示空图片

swift - TextField 值可以在 TextFieldStyle 中使用吗?

ios - 我将如何解析来自 nsdictionary 的数组数据?

ios - 我的文件存在,但 fileExistsAtPath 总是返回 false

ios - 是否可以通过 Springboard 调整在 SBApplication 中设置 userInfo?