【问题标题】:SwiftUI - @Published property is not updating view from coordinatorSwiftUI - @Published 属性未从协调器更新视图
【发布时间】:2020-10-21 11:16:10
【问题描述】:

我在UISearchBar 周围使用了一个包装器,当将@Published 属性传递到此SearchBar 包装器与TextField 时,我看到了不同的行为。

两者都按预期更新@ObservedObject var query = Query()@Published var input 属性,但只有TextField 更新SearchSheet 视图。我希望在 input 已在 SearchBar 中更改时更新视图,类似于从 TextField 更新的方式。

编辑:我已更新我的问题以包含 ContentView,其中看起来此问题特定于从 NavigationBarItem 中的 Button 调用工作表时。

struct ContentView: View {
    @State var showingSearch = false
    
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello World")
            }
            .navigationBarItems(trailing:
                Button(action: {
                    self.showingSearch.toggle()
                }) {
                    Image(systemName: "magnifyingglass")
                }
                .sheet(isPresented: $showingSearch) {
                    SearchSheet(isPresented: self.$showingSearch)
                }
            )
        }
    }
}
class Query: ObservableObject {
    @Published var input = "" {
        didSet {
            // Called as expected in both cases but only TextField updates the SearchSheet view.
        }
    }
}
struct SearchSheet: View {
    @ObservedObject var query = Query()

    var body: some View {
        VStack {
            // Does not update the SearchSheet view. I would like it understand why and how to update it.
            SearchBar(text: $query.input, placeholder: "Search")
            // Does update the SearchSheet view.
            TextField("Search", text: $query.input)

            Text("\(query.input)")
        }
    }
}
import SwiftUI

struct SearchBar: UIViewRepresentable {

    @Binding var text: String
    var placeholder: String

    class Coordinator: NSObject, UISearchBarDelegate {

        @Binding var text: String

        init(text: Binding<String>) {
            _text = text
        }

        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            text = searchText
        }
    }

    func makeCoordinator() -> SearchBar.Coordinator {
        return Coordinator(text: $text)
    }

    func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
        let searchBar = UISearchBar(frame: .zero)
        searchBar.delegate = context.coordinator
        searchBar.placeholder = placeholder
        searchBar.searchBarStyle = .minimal
        searchBar.autocapitalizationType = .none
        return searchBar
    }

    func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {
        uiView.text = text
    }
}

struct SearchBar_Previews: PreviewProvider {
    @State private static var text = ""
    
    static var previews: some View {
        SearchBar(text: $text, placeholder: "Search")
    }
}

【问题讨论】:

  • 在 Xcode 11.4 / iOS 13.4 上可以正常工作
  • 谢谢@Asperi,你说得对,在一个新项目中这似乎确实按预期工作。我已更新以包含导致此失败的 ContentView。

标签: ios swift swiftui


【解决方案1】:

将工作表的显示从navigationBarItems 移出可解决此问题。当时我认为这是一个错误。

.navigationBarItems(trailing:
    Button(action: {
        self.showingSearch.toggle()
    }) {
        Image(systemName: "magnifyingglass")
    }
)
.sheet(isPresented: $showingSearch) {
    SearchSheet(isPresented: self.$showingSearch)
}

【讨论】:

    猜你喜欢
    • 2021-03-23
    • 2021-10-14
    • 2020-03-08
    • 2022-01-04
    • 2020-11-12
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多