我已经用SwiftUI编写了一个列表。我也有一个TextField对象,用作搜索栏。我的代码如下:
import SwiftUI
struct MyListView: View {
@ObservedObject var viewModel: MyViewModel
@State private var query = ""
var body: some View {
NavigationView {
List {
// how to listen for changes here?
// if I add onEditingChange here, Get the value only after the user finish search (by pressing enter on the keyboard)
TextField(String.localizedString(forKey: "search_bar_hint"), text: self.$query) {
self.fetchListing()
}
ForEach(viewModel.myArray, id: \.id) { arrayObject in
NavigationLink(destination: MyDetailView(MyDetailViewModel(arrayObj: arrayObject))) {
MyRow(arrayObj: arrayObject)
}
}
}
.navigationBarTitle(navigationBarTitle())
}
.onAppear(perform: fetchListing)
}
private func fetchListing() {
query.isEmpty ? viewModel.fetchRequest(for: nil) : viewModel.fetchRequest(for: query)
}
private func navigationBarTitle() -> String {
return query.isEmpty ? String.localizedString(forKey: "my_title") : query
}
}
我现在遇到的问题是列表仍然留在键盘后面:(。我如何设置列表填充的底部或边缘插图(或者其他什么方法,我完全打开了),以便列表的滚动在上方结束
键盘上的“大小”列表也会自动调整,具体取决于键盘是打开还是关闭。问题看起来像这样:
请提供任何建议,帮助我,我真的不知道该怎么做:(。我是一个SwiftUI初学者,正在尝试学习它:)。
答案 0 :(得分:0)
您可以尝试以下操作,并自己添加详细的动画。
@ObservedObject var keyboard = KeyboardResponder()
var body: some View {
NavigationView {
List {
// how to listen for changes here?
// if I add onEditingChange here, Get the value only after the user finish search (by pressing enter on the keyboard)
TextField("search_bar_hint", text: self.$query) {
self.fetchListing()
}
ForEach(self.viewModel, id: \.self) { arrayObject in
Text(arrayObject)
}
}.padding(.bottom, self.keyboard.currentHeight).animation(.easeIn(duration: self.keyboard.keyboardDuration))
.navigationBarTitle(self.navigationBarTitle())
}
.onAppear(perform: fetchListing)
}
class KeyboardResponder: ObservableObject {
@Published var currentHeight: CGFloat = 0
@Published var keyboardDuration: TimeInterval = 0
private var anyCancellable: Set<AnyCancellable> = Set<AnyCancellable>()
init() {
let publisher1 = NotificationCenter.Publisher(center: .default, name: UIResponder.keyboardWillShowNotification).map{ notification -> Just<(CGFloat, TimeInterval)> in
guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {return Just((CGFloat(0.0), 0.0)) }
guard let duration:TimeInterval = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return Just((CGFloat(0.0), 0.0)) }
return Just((keyboardSize.height, duration))}
let publisher2 = NotificationCenter.Publisher(center: .default, name: UIResponder.keyboardWillHideNotification) .map{ notification -> Just<(CGFloat, TimeInterval)> in
guard let duration:TimeInterval = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return Just((CGFloat(0.0), 0.0)) }
return Just((0.0, duration))}
Publishers.Merge(publisher1, publisher2).switchToLatest().subscribe(on: RunLoop.main).sink(receiveValue: {
if $0.1 > 1e-6 { self.currentHeight = $0.0 }
self.keyboardDuration = $0.1
}).store(in: &anyCancellable)
}
}
答案 1 :(得分:0)
解决键盘填充问题的方法类似于E.coms。也可以使用kontiki在此处编写的类:
How to make the bottom button follow the keyboard display in SwiftUI
我遇到的问题是由于视图层次结构中的状态更改,这是由于引用类型的多个实例发布了类似的状态更改。
我的视图模型是引用类型,它们发布对其模型的更改(值类型)。但是,这些视图模型还包含处理网络请求的引用类型。对于我渲染的每个视图(每一行),我分配一个新的视图模型实例,该实例也创建一个新的网络服务实例。继续这种模式,所有这些网络服务还创建并分配了新的网络管理器。