Как извлечь состояние из массива структурных представлений? SwiftUI - PullRequest
1 голос
/ 10 марта 2020

У меня проблема с извлечением состояния из массива структур SwiftUI.

У меня есть структура для карт, которые содержат topText и bottomText. У меня есть другая структура, которая является формой для компонентов ввода, таких как карта. Я храню эти карты в массиве, добавляя все больше и больше по нажатию кнопки +. В родительском представлении у меня есть foreach для этого массива, поэтому они отображаются динамически.

У меня возникла проблема с попыткой извлечь значение состояния из этих структур. Карты содержат состояние для topText и bottomText. При нажатии кнопки сохранения в родительском массиве (там, где существует массив карточек), он перебирает массив карточек и печатает их состояние с помощью метода get. Тем не менее, он не печатает текущее состояние этих карт. Он печатает пустую строку. Я считаю, что это происходит потому, что когда я добавляю структуру, она просто копирует мертвую структуру, а не реальную структуру с сохранением состояния.

Верны ли мои предположения? Или это ошибка в swiftUI? У кого-нибудь есть идеи о том, как правильно это сделать? Я просто хочу получить вход от карточек всякий раз, когда нажимается кнопка. Тем не менее, он должен быть динамическим c, поскольку пользователь может нажимать кнопку + сколько угодно раз и продолжать делать больше карточек.

Вот код для карточки:

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
    }
}

А вот родительское представление:


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")
                }
            )        }

    }

}

1 Ответ

1 голос
/ 10 марта 2020

Вам нужно знать, как использовать 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()
    ...

Далее мы связываем экземпляр model с textFields.

VStack(spacing: 30){
    TextField("Top text...", text: self.$model.topText).multilineTextAlignment(.center)
    Divider()
    TextField("Bottom text...", text: self.$model.bottomText)
}

И затем мы можем извлечь данные из класса модели, используя существующие функции top и bottom, например:

func getBottomText() -> String{
    print("BOTTOM: \(self.model.bottomText)")
    return self.model.bottomText
}

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

Вуаля! Это сейчас должно работать. Этот ответ на другой вопрос { ссылка } должен помочь вам, он написан всесторонне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...