[英]TextField always on keyboard top with SwiftUI
i have this我有这个
struct ContentView: View {
var body: some View {
ZStack(alignment: Alignment.bottom) {
List {
Text("Default text").foregroundColor(Color.red)
}
TextField("Placeholder", text: .constant(""))
.frame(minHeight: 30)
.cornerRadius(8.0)
.padding(10)
.background(Color.blue)
}
}
}
Actually, when i focus on the TextField, keyboard hide this textfield.实际上,当我专注于 TextField 时,键盘会隐藏此文本字段。
Is there a simple solution in SwiftUI to keep the textfield always on keyboard's top ? SwiftUI 中是否有一个简单的解决方案可以使文本字段始终位于键盘顶部?
Here is a snippet that observes NotificationCenter
notifications related the keyboard, and changes the height of a spacer view based on the computed keyboard height.这是观察与键盘相关的NotificationCenter
通知的片段,并根据计算出的键盘高度更改间隔视图的高度。
import Combine
struct ExampleView: View {
@State var keyboardHeight: CGFloat = 0
var cancellables: Set<AnyCancellable> = []
init() {
NotificationCenter.default.publisher(for: UIResponder.keyboardWillChangeFrameNotification)
.merge(with: NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification))
.compactMap({ notification in
guard let keyboardFrameValue: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return nil }
let keyboardFrame = keyboardFrameValue.cgRectValue
// If the rectangle is at the bottom of the screen, set the height to 0.
if keyboardFrame.origin.y == UIScreen.main.bounds.height {
return 0
} else {
// Adjust for safe area
return keyboardFrame.height - (UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0)
}
})
.assign(to: \.keyboardHeight, on: self)
.store(in: &cancellables)
}
var body: some View {
VStack {
// Your content here
Spacer()
.frame(height: keyboardHeight)
}
}
}
I wrote a Swift package that handles this for you.我写了一个 Swift 包来为你处理这个问题。 It exposes a KeyboardObservingView
that wraps your content.它公开了一个包装您的内容的KeyboardObservingView
。
It's available here: https://github.com/nickffox/KeyboardObserving它可以在这里找到: https : //github.com/nickffox/KeyboardObserving
You would use it like this:你会像这样使用它:
var body: some View {
KeyboardObservingView {
List {...}
TextField("Placeholder", text: .constant(""))
.frame(minHeight: 30)
.cornerRadius(8.0)
.padding(10)
.background(Color.blue)
}
}
I've tried different approaches, and none of them worked for me.我尝试了不同的方法,但没有一个对我有用。 This one below is the only one that worked for different devices.下面的这个是唯一一个适用于不同设备的。
Add this extension in a file:在文件中添加此扩展名:
import SwiftUI
import Combine
extension View {
func keyboardSensible(_ offsetValue: Binding<CGFloat>) -> some View {
return self
.padding(.bottom, offsetValue.wrappedValue)
.animation(.spring())
.onAppear {
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { notification in
let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first
let bottom = keyWindow?.safeAreaInsets.bottom ?? 0
let value = notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect
let height = value.height
offsetValue.wrappedValue = height - bottom
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { _ in
offsetValue.wrappedValue = 0
}
}
}
}
In your view, you need a variable to bind offsetValue:在您看来,您需要一个变量来绑定 offsetValue:
struct IncomeView: View {
@State private var offsetValue: CGFloat = 0.0
var body: some View {
VStack {
//...
}
.keyboardSensible($offsetValue)
}
}
Just gonna drop a simple, easy and a bit hacky solution I found to handle the keyboard:只是要放弃一个简单,容易且有点hacky的解决方案,我发现它可以处理键盘:
struct ContentView : View {
@State private var name = ""
@State private var keyboardUp = false
private var keyboardHeight: CGFloat { 150 }
var body: some View {
NavigationView {
Spacer()
Form {
TextField($name, placeholder: Text("Name"), onEditingChanged: { { self.keyboardUp = $0 })
}.offset(y: keyboardUp ? -keyboardHeight : 0)
.animation(.basic())
.navigationBarTitle(Text("Title"))
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.