如何使用SwiftUI在多个屏幕上获取键盘高度并移动按钮 [英] How to get the keyboard height on multiple screens with SwiftUI and move the button
问题描述
以下代码在显示键盘时获取键盘高度,并按键盘高度移动按钮.
The following code gets the keyboard height when the keyboard is displayed and moves the button by the keyboard height.
在过渡源(ContentView)和过渡目标(SecibdContentView)上以相同的方式执行此移动,但是按钮在过渡目标处不移动.
This movement is performed in the same way at the transition source (ContentView) and the transition destination (SecibdContentView), but the button does not move at the transition destination.
如何使按钮在多个屏幕上移动相同?
How can I make the buttons move the same on multiple screens?
import SwiftUI
struct ContentView: View {
@ObservedObject private var keyboard = KeyboardResponder()
var body: some View {
NavigationView {
VStack {
Text("ContentView")
Spacer()
NavigationLink(destination: SecondContentView()) {
Text("Next")
}
.offset(x: 0, y: -keyboard.currentHeight)
}
}
}
}
import SwiftUI
struct SecondContentView: View {
@ObservedObject private var keyboard = KeyboardResponder()
var body: some View {
VStack {
Text("SubContentView")
Spacer()
NavigationLink(destination: ThirdContentView()) {
Text("Next")
}
.offset(x: 0, y: -keyboard.currentHeight)
}
}
}
class KeyboardResponder: ObservableObject {
private var _center: NotificationCenter
@Published var currentHeight: CGFloat = 0
init(center: NotificationCenter = .default) {
_center = center
_center.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
_center.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
deinit {
_center.removeObserver(self)
}
@objc func keyBoardWillShow(notification: Notification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
currentHeight = keyboardSize.height
}
}
@objc func keyBoardWillHide(notification: Notification) {
currentHeight = 0
}
}
推荐答案
使用ViewModifier
您可以使用swiftui的ViewModifier简单得多
Using ViewModifier
You can use ViewModifier of swiftui is much simpler
import SwiftUI
import Combine
struct KeyboardAwareModifier: ViewModifier {
@State private var keyboardHeight: CGFloat = 0
private var keyboardHeightPublisher: AnyPublisher<CGFloat, Never> {
Publishers.Merge(
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.compactMap { $0.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue }
.map { $0.cgRectValue.height },
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in CGFloat(0) }
).eraseToAnyPublisher()
}
func body(content: Content) -> some View {
content
.padding(.bottom, keyboardHeight)
.onReceive(keyboardHeightPublisher) { self.keyboardHeight = $0 }
}
}
extension View {
func KeyboardAwarePadding() -> some View {
ModifiedContent(content: self, modifier: KeyboardAwareModifier())
}
}
在您看来
struct SomeView: View {
@State private var someText: String = ""
var body: some View {
VStack {
Spacer()
TextField("some text", text: $someText)
}.KeyboardAwarePadding()
}
}
KeyboardAwarePadding()
将自动在您的视图中添加一个填充,这更加优雅.
KeyboardAwarePadding()
will automatically add a padding in your view, It's more elegant.
这篇关于如何使用SwiftUI在多个屏幕上获取键盘高度并移动按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!