Используйте NavigationButton с запросом к серверу в SwiftUI - PullRequest
4 голосов
/ 14 июня 2019

Как я могу заставить NavigationButton ждать ответа сервера, прежде чем перейти к следующему представлению?

Я пробовал что-то подобное

NavigationButton(destination: LogonView(),  onTrigger: { () -> Bool in
                    return self.viewModel.responseReceived
                }) {
                    Text("OK")
                    }.tapAction {
                        self.viewModel.fetch(companyID: &self.companyID)
                }

но tapAction никогда не вызывается.

Я заставил его работать, используя Button:

Button(action: {
        self.viewModel.fetch(companyID: &self.companyID)
    }) {
        Text("OK")
    }.presentation(viewModel.shouldPresentModal ? Modal(LogonView() : nil)

    // in ViewModel
    var shouldPresentModal = false { // set to true when data are received from server
            didSet {
                didChange.send(())
            }
        }

но мне нужно показать следующий вид в навигации, а не модально

Спасибо!

1 Ответ

2 голосов
/ 19 июня 2019

Сорин, по крайней мере, в моем понимании, SwiftUI предназначен только для уровня представления, он не должен заменять вашу модель. И он «реактивный», в отличие от UIKit, поэтому заставить представление выполнять действия, подобные модели, очень сложно.

Я бы подошел к задаче так:

class LoginModel : BindableObject {

    var didChange = PassthroughSubject<LoginModel, Never>()

    private(set) var username: String? {
        didSet {
            didChange.send(self)
        }
    }

    func load() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            self.username = "Sorin"
        }
    }
}

Это объект модели, инкапсулирующий наш код для входа. Асинхронная операция здесь моделируется простой задержкой.

А затем, вид:

public struct LoginScreen: View {

    @ObjectBinding var loginObject = LoginModel()

    public var body: some View {
        Group {
            if login.username == nil {
                Text("Trying to login, please wait...")
            } else {
                Text("Successful login, the username is \(loginObject.username!)")
            }
        }.onAppear {
            self.loginObject.load()
        }
    }
}

Существуют более эффективные способы "связывания" с модельным объектом, но мы, разумеется, рассмотрим здесь только голый пример.

Ваш NavigationButton будет ссылаться только на LoginScreen, без какого-либо другого кода или триггера. Первоначально на экране отобразится Trying to login, please wait..., а через 5 секунд изменится на Successful login, the username is Sorin. Очевидно, вы могли бы сойти с ума и заменить мой текст здесь, что вы можете.

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