我有一个KeyboardObserver,它可以观察键盘上的变化并计算所需的高度以如下调整视图:
final class KeyboardObserver: ObservableObject {
public var lastViewRect = CGRect()
@Published var keyboardMinY: CGFloat = 0 {
didSet {
if keyboardMinY == 0 {
lastViewAdjustment = 0
} else {
lastViewAdjustment = keyboardMinY - lastViewRect.maxY
}
}
}
@Published var lastViewAdjustment: CGFloat = 0
// keyboardWillShow notification may be posted repeatedly,
// this flag makes sure we only act once per keyboard appearance
@Published var keyboardIsHidden = true
func addObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardDidHide(notification:)), name: UIResponder.keyboardDidHideNotification, object: nil)
}
func removeObserver() {
NotificationCenter.default.removeObserver(self)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc func keyBoardWillShow(notification: Notification) {
if keyboardIsHidden {
keyboardIsHidden = false
if let rect = notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect {
keyboardMinY = rect.minY
}
}
}
@objc func keyBoardDidHide(notification: Notification) {
keyboardIsHidden = true
keyboardMinY = 0
}
}
我在如下视图中使用它:
struct SignUpView: View {
@ObservedObject private var keyboardObserver = KeyboardObserver()
var body: some View {
VStack(alignment: .leading) {
...
ScrollView {
IndicatorTextField("Full Name", .imageUserBlue, .turquoiseBlue)
.padding(.top, 48)
IndicatorTextField("Email Address", .imageEmail, .turquoiseBlue)
.padding(.top, 8)
IndicatorTextField("Home Town", .imageLocation, .turquoiseBlue)
.padding(.top, 8)
IndicatorTextField("Password", .imageLock, .reddishPink)
.padding(.top, 8)
IndicatorTextField("Date of Birth", .imageCalender, .reddishPink)
.padding(.top, 8)
IndicatorTextField("Gender", .imageUserRed, .reddishPink)
.padding(.top, 8)
Spacer()
.frame(width: 0, height: -keyboardObserver.lastViewAdjustment)
.animation(.linear(duration: 1))
}
.background(GeometryGetter(rect: $keyboardObserver.lastViewRect))
...
}
.background(BackgroundImage(.imageBgSignup))
.edgesIgnoringSafeArea(.all)
.onAppear { self.keyboardObserver.addObserver() }
.onDisappear { self.keyboardObserver.removeObserver() }
}
}
IndicatorTextField仅是自定义的TextField。
我想在键盘隐藏物上添加动画,即,当Spacer的高度大约为135变为0时,它会快速变化而没有动画。
我也尝试用withAnimation
块包装Spacer,但没有取得丰硕的成果。
有什么建议吗?