简体   繁体   中英

@Published property has a delay when used as navigationBar's title

I just noticed that when using a @Published property as navigation's title, there is some delay while displaying the value (but if the subscription is made on the ViewModel's init, it display instantly), but also the delay is only on the navigationBar, because the Text view display the value instantly:

class ContentViewModel: ObservableObject {
    @Published var text: String = ""
    private var cancellables = Set<AnyCancellable>()

    func onAppear() {
        Just("onAppear text")
            .sink { [weak self] in
                self?.text = $0
            }
            .store(in: &cancellables)
    }
}

struct ContentView: View {
    @ObservedObject var viewModel: ContentViewModel

    var body: some View {
        Text(viewModel.text)
            .padding()
            .navigationTitle(viewModel.text)
            .onAppear(perform: viewModel.onAppear)
    }
}

struct MainView: View {
    @StateObject var viewModel = ContentViewModel()

    var body: some View {
        NavigationView {
            NavigationLink("Open View") {
                ContentView(viewModel: viewModel)
            }
        }
    }
}

Note: Using the Toolbar also allows to display the title instantly:

.toolbar(content: {
    ToolbarItemGroup(placement: .principal) {
       Text(viewModel.text)
           .fixedSize()
    }
})

Note: But I minor drawback with the toolbar is that the text is not truncating, if I have a long text (as in my real app can be dynamic) is overflowing and showing below leading/trailing buttons. Probably is related to the fixedSize() (but if I don't apply, the View is not visible, looks like doesn't have the proper layout update)

in fact the lag exist, but you can use init instead of onAppear to load staff:

class ContentViewModel: ObservableObject {
    @Published var text: String = ""
    private var cancellables = Set<AnyCancellable>()

    init() { // THIS
        Just("onAppear text")
            .sink { [weak self] in
                self?.text = $0
            }
            .store(in: &cancellables)
    }
}

struct TheView: View {
    @ObservedObject var viewModel: ContentViewModel

    var body: some View {
        Text(viewModel.text)
            .padding()
            .navigationTitle(viewModel.text)
            //.onAppear(perform: viewModel.onAppear) THIS
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM