键盘出现/消失时调整带有 TextField 的 SwiftUI 列表
Posted
技术标签:
【中文标题】键盘出现/消失时调整带有 TextField 的 SwiftUI 列表【英文标题】:SwiftUI List with TextField adjust when keyboard appears/disappears 【发布时间】:2019-11-26 18:00:02 【问题描述】:我用 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 初学者,正在努力学习它 :)。
【问题讨论】:
查看***.com/questions/57739966/… 【参考方案1】:您可以尝试以下方法并自己添加详细的动画。
@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)
【讨论】:
【参考方案2】:键盘填充问题的解决方法就像 E.coms 建议的那样。也可以使用 kontiki 在这里编写的类:
How to make the bottom button follow the keyboard display in SwiftUI
我遇到的问题是由于多个引用类型实例发布了类似的状态更改,导致视图层次结构中的状态更改。
我的视图模型是引用类型,它发布对其模型的更改,它们是值类型。然而,这些视图模型也包含处理网络请求的引用类型。对于我渲染的每个视图(每一行),我分配了一个新的视图模型实例,该实例也创建了一个新的网络服务实例。继续这种模式,这些网络服务中的每一个也会创建和分配新的网络管理器。
【讨论】:
以上是关于键盘出现/消失时调整带有 TextField 的 SwiftUI 列表的主要内容,如果未能解决你的问题,请参考以下文章
NativeScript - ios如何在键盘出现时调整视图