【问题标题】:@Published property has a delay when used as navigationBar's title@Published 属性在用作导航栏的标题时有延迟
【发布时间】:2021-12-28 01:22:45
【问题描述】:

我刚刚注意到,当使用@Published 属性作为导航的标题时,显示值时会有一些延迟(但如果订阅是在 ViewModel 的初始化上进行的,它会立即显示),而且延迟仅在导航栏,因为Text 视图会立即显示值:

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

注意:使用工具栏还可以立即显示标题:

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

注意:但我使用工具栏的小缺点是文本不会被截断,如果我有一个长文本(因为在我的真实应用程序中可以是动态的)溢出并显示在前导/下方尾随按钮。可能与fixedSize()有关(但如果我不申请,视图是不可见的,看起来没有正确的布局更新)

【问题讨论】:

    标签: ios swift swiftui swiftui-navigationview


    【解决方案1】:

    其实滞后是存在的,但是你可以用 init 代替 onAppear 来加载人员:

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

    【讨论】:

    • 感谢您添加答案,是的,我注意到它在 init 上工作,但我希望使用 onAppear 使其工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多