Как использовать BindableObjects (EnviromentObject)? - PullRequest
0 голосов
/ 07 июня 2019

Я использую новый SwiftUI. У меня есть класс UserUpdate, который является Bindable Object, и я хочу изменить эти переменные и автоматически обновить пользовательский интерфейс.

Я успешно обновляю эти значения, но представления в моей структуре пользовательского интерфейса не обновляются, когда я изменяю переменную в классе UserUpdate.

Это только изменяется, когда я изменяю переменную @EnviromentObject в самой структуре пользовательского интерфейса.

Это мой класс связываемых объектов:

final class UserUpdate: BindableObject {
    let didChange = PassthroughSubject<Any, Never>()

    var allUsers: [User] = [] {
        didSet {
            print(allUsers)
            didChange.send(allUsers)
        }
    }

    var firstName: String = "" {
        didSet {
            didChange.send(firstName)
        }
    }

    var lastName: String = "" {
        didSet {
            didChange.send(lastName)
        }
    }
}

Это мой класс пользователя:

struct User: Identifiable {
    let id: Int
    let firstName, lastName: String
}

Вот как я настраиваю свой интерфейс:

struct ContentView : View {
    @EnvironmentObject var bindableUser: UserUpdate

    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {
                Text("All Users:").bold().padding(.leading, 10)
                List {
                    ForEach(bindableUser.allUsers) { user in
                        Text("\(user.firstName) \(user.lastName)")
                    }
                }
            }
        }
    }
}

Здесь я изменяю переменные в UserUpdate:

class TestBind {
    static let instance = TestBind()

    let userUpdate = UserUpdate()

    func bind() {
        let user = User(id: userUpdate.allUsers.count, firstName: "Heyy", lastName: "worked")
        userUpdate.allUsers.append(user)
    }
}

Ответы [ 2 ]

1 голос
/ 08 июня 2019

Если я не ошибаюсь, вы должны внедрить экземпляр UserUpdate в свой ContentView, возможно, в SceneDelegate, используя ContentView().environmentObject(UserUpdate()).

В этом случае у вас есть 2 разных экземпляра класса UserUpdate, первый из которых создан в SceneDelegate, а второй - в TestBind классе.

Проблема в том, что у вас есть один экземпляр, который связан с просмотром (и будет запускать перезагрузку представления при обновлении), и тот, который вы фактически изменяете (в TestBind классе), который совершенно не связан с представлением.

Вы должны найти способ использовать тот же экземпляр в представлении и в классе TestBind (например, используя ContentView().environmentObject(TestBind.instance.userUpdate)

1 голос
/ 08 июня 2019

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

Например этим:

struct ContentView : View {
@EnvironmentObject var networkManager: NetworkManager

var body: some View {
    VStack {
        Button(action: {
            self.networkManager.getAllCourses()
        }, label: {
            Text("Get All Courses")
        })

        List(networkManager.courses.identified(by: \.name)) {
            Text($0.name)
        }
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...