SwiftUI - Обновление @State при глобальных изменениях - PullRequest
0 голосов
/ 28 октября 2019

Я хотел бы обновить элемент пользовательского интерфейса в обзорном виде при изменении данных в другом виде.

Я посмотрел в @EnvironmentalObject и @Binding. Тем не менее, обновление любого из этих объектов не приводит к перезагрузке представления. Изменяется только при рендеринге @State force.
Кроме того, в случае, описанном ниже, ChangeView не является дочерним элементом OverviewView. Поэтому @Binding в любом случае не является опцией.

Data.swift

struct ExampleData : Hashable {
 var id: UUID
 var name: String
}

var globalVar: ExampleData = ExampleData(id: UUID(), name:"")

OverviewView.swift

struct OverviewView: View {
    @State private var data: ExampleData = globalVar
    var body: some View {
       Text(data.name)
    }
}

ChangeView.swift

struct ChangeView: View {
    @State private var data: ExampleData = globalVar
    var body: some View {
       TextField("Name", text: $data.name, onEditingChanged: { _ in 
          globalVar = data }, onCommit: { globalVar = data })
    }
}

Изменения внутри ChangeView TextField обновят globalVar. Однако это не приведет к обновлению текста в OverviewView при переключении обратно на представление.

Я знаю, что использование глобальных переменных - это "уродливое" кодирование. Как мне обрабатывать данные, которые будут использоваться во множестве несвязанных представлений?

Посоветуйте, пожалуйста, как лучше справиться с такой ситуацией.

1 Ответ

2 голосов
/ 28 октября 2019

OverviewView и ChangeView содержат разные копии структуры ExampleData в своих переменных data (При назначении структуры другой переменной вы фактически копируете ее, а не ссылаетесь на нее как объект.)не повлияет на других.

@ EnvironmentObject соответствует вашим требованиям.

Вот пример:
Поскольку мы используем @EnvironmentObject, вам нужно либо преобразовать ExampleData в класс, либо использовать класс для его хранения. Я буду использовать последний.

class ExampleDataHolder: ObservableObject {
    @Published var data: ExampleData = ExampleData(id: UUID(), name:"")
}

struct CommonAncestorOfTheViews: View {
    var body: some View {
       CommonAncestorView()
          .environmentObject(ExampleDataHolder())
    }
}

struct OverviewView: View {
    @EnvironmentObject var dataHolder: ExampleDataHolder

    var body: some View {
       Text(dataHolder.data.name)
    }
}

struct ChangeView: View {
    @EnvironmentObject var dataHolder: ExampleDataHolder

    var body: some View {
       TextField("Name", text: $dataHolder.data.name)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...