I am using swiftUI. And I used NotificationCenter to move textfield when keyboard appears by using keyboardWillShowNotification and keyboardWillHideNotification. But every time I touch textfield and call keyboard, keyboardWillShowNotification is sended twice but keyboardWillHideNotification is sended only once. And I can't find reason for it
The code of custom view that I have problem is below
import SwiftUI
import Combine
class KeyboardObserver:ObservableObject{
@Published var activeState:Bool = false
var subscribeCount = 0
func setNotification(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object:nil)
subscribeCount += 1
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(notification: Notification){
print("before appear state: \(activeState), subCount: \(subscribeCount)")
activeState = true
print("after appear state: \(activeState), subCount: \(subscribeCount)")
}
@objc func keyboardWillHide(notification: Notification){
activeState = false
print("disappear state: \(activeState), subCount: \(subscribeCount)")
}
}
struct MovingTextfield: View {
@State var active: Bool = false
@ObservedObject var observer = KeyboardObserver()
@Binding var keywordValue: String
var body: some View {
VStack{
Text("\(active)")
Text("\(observer.activeState)")
HStack{
Spacer()
TextField("\(Text("text input").font(.title))", text: $keywordValue)
.foregroundStyle(.black).font(.title)
.multilineTextAlignment(.center)
.disableAutocorrection(true)
Spacer()
}
}
.onAppear{
observer.setNotification()
print("setting complete")
}
}
}
And ContentView is below
import SwiftUI
struct ContentView: View {
@State var keywordValue = "ABCDEFG"
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
MovingTextfield(keywordValue: $keywordValue)
}
.padding()
}
}
#Preview {
ContentView()
}
I found out that keyboardWillShowNotification is called twice. since the selected that I named keyboardWillShow was called twice. And I could not go further.
@ObservedObject
where you own the object -- it should be@StateObject
keyboardWillShow
is only called once in my tests. On MacOS 15, Xcode 16, target iOS-18, tested on real ios device. Note, as mentioned you should use@StateObject private var observer = KeyboardObserver()
and use@State private var ...