在下面的帮助下,我能够跟随键盘显示上的按钮。 然而,动画不能很好地应用。
How to show complete List when keyboard is showing up in SwiftUI
import SwiftUI
import Combine
import UIKit
class KeyboardResponder: ObservableObject {
let willset = PassthroughSubject<CGFloat, Never>()
private var _center: NotificationCenter
@Published var currentHeight: CGFloat = 0
var keyboardDuration: TimeInterval = 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
guard let duration:TimeInterval = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return }
keyboardDuration = duration
}
}
@objc func keyBoardWillHide(notification: Notification) {
currentHeight = 0
}
}
import SwiftUI
struct Content: View {
@ObservedObject var keyboard = KeyboardResponder()
var body: some View {
VStack {
Text("text")
Spacer()
NavigationLink(destination: SubContentView()) {
Text("Done")
}
}
.padding(.bottom, keyboard.currentHeight)
animation(Animation.easeInOut(duration: keyboard.keyboardDuration))
}
}
最佳答案
您的主要问题是您使用的是隐式动画。不仅它可能会为您可能不想制作动画的东西制作动画,而且您永远不应该在容器上应用 .animation() 。在 SwiftUI 文档中的几个警告中,这是其中之一:
Use this modifier on leaf views rather than container views. The animation applies to all child views within this view; calling animation(_:) on a container view can lead to unbounded scope.
来源:https://developer.apple.com/documentation/swiftui/view/3278508-animation
修改后的代码删除了隐式的 .animation()
调用,并用两个隐式的 withAnimation
闭包替换了它。
我还用 keyboardFrameEndUserInfoKey
替换了 keyboardFrameEndUserInfoKey
,第二次调用给出了无用的几何图形。
class KeyboardResponder: ObservableObject {
let willset = PassthroughSubject<CGFloat, Never>()
private var _center: NotificationCenter
@Published var currentHeight: CGFloat = 0
var keyboardDuration: TimeInterval = 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.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
guard let duration:TimeInterval = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return }
keyboardDuration = duration
withAnimation(.easeInOut(duration: duration)) {
self.currentHeight = keyboardSize.height
}
}
}
@objc func keyBoardWillHide(notification: Notification) {
guard let duration:TimeInterval = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return }
withAnimation(.easeInOut(duration: duration)) {
currentHeight = 0
}
}
}
struct ContentView: View {
@ObservedObject var keyboard = KeyboardResponder()
var body: some View {
return VStack {
Text("text \(keyboard.currentHeight)")
TextField("Enter text", text: .constant(""))
Spacer()
NavigationLink(destination: Text("SubContentView()")) {
Text("Done")
}
}
.padding(.bottom, keyboard.currentHeight)
// .animation(Animation.easeInOut(duration: keyboard.keyboardDuration))
}
}
关于swiftui - 如何使底部按钮跟随 SwiftUI 中的键盘显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57739966/