iOS/SwiftUI

[SwiftUI] 키보드(keyboard) 활성화 / 비활성화 컨트롤 하기

건우(gunoo) 2023. 6. 26. 01:18
목차)
1. Keyboard 비활성화 시키기

2. Keyboard 활성화 감지하기

3. Keyboard 비활성화 감지하기

4. 등록한 observer 해제하기

5. extension 으로 적용하기

1. Keyboard 비활성화 시키기

UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)

[코드 설명]

1) UIResponder 프로토콜에서 정의된 resignFirstResponder 메서드에 대한 액션을 보낸다. 

2) resignFirstResponder 메서드는 first responder 객체, 일반적으로 텍스트 필드텍스트 뷰에서 포커스를 제거하는 역할을 한다.

[예시]

...
    VStack(spacing:8){
                TextField("입력하기", text: $text)
                    .padding(.horizontal, 16)
                Button(action:{
                    UIApplication.shared.sendAction(
                        #selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil
                    )
                }){
                    Text("키보드 감추기")
                }
            }
...

 

2.  Keyboard 활성화 감지하기

 NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { _ in
           
           //키보드가 나타나면 실행할 코드 작성
           
        }

[코드 설명]

1) NotificationCenter.default.addObserver

- 특정 동작을 감지하기 위해 옵저버를 등록한다.

 

2) UIResponder.keyboardWillShowNotification

- 키보드가 나타날 때 발생하는 Notification

- Notification이 발생하면 등록된 옵저버에게 알린다.

[예시]

앱을 초기화 하는 시점에 onAppear() 를 활용하여 키보드가 활성화 될 때 감지하는 옵저버를 등록한다.

 

var body: some View {
    VStack{

    }
    .onAppear{
        NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { _ in
            print("키보드 나타남")
        }
    }
  }

 

keyboard 가 활성화 될 때 감지

3. Keyboard 비활성화 감지하기

 NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { _ in
           
           //키보드가 사라지면 작동시킬 코드 작성
           
        }

[코드 설명]

1) UIResponser.keyboardWillHideNotification

- 키보드가 사라질 때 발생하는 Notification

- Notification 이 발생하면 등록한 옵저버에 알린다.

[예시]

앱을 초기화 하는 시점에 onAppear() 를 활용하여 키보드가 사라질 때 감지하는 옵저버등록한다.

 

var body: some View {
    VStack{

    }
    .onAppear{
        NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { _ in
            print("키보드 비활성화")
        }
    }
  }

 

keyboard 비활성화 될 때 감지

4.  등록한 Observer 해제하기

전역적으로 키보드의 활성화, 비활성화를 감지하여 같은 액션을 실행한다면 문제가 되지 않지만,

특정 뷰에서만 키보드의 활성화 비활성화를 감지한다면,
키보드 감지 observer 등록 후, View 를 벗어 날 때 등록한 observer를 해제해 주어야 한다. 

 

// keyboardWillShowNotification 해제
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)

// keyboardWillHideNotification 해제
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)

 

위 코드는 키보드 활성화 / 비활성화 감지 옵저버를 해제하는 코드이다.

 

적용 방법은 아래와 같이 특정 view를 벗어나는 시점에 실행되는 onDisappear() 에서 작동 할 수 있도록 해주면 된다.

 

var body: some View {
    VStack{

    }
    .onAppear{
    	//키보드 활성화 감지 옵저버 등록
        NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { _ in
            print("키보드 나타남")
        }
    }
    .onDisappear{
    	//키보드 활성화 감지 옵저버 해제
    	NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    }
  }

5. extension 으로 적용하기

키보드 활성화 / 비활성화는 View 에서 발생하는 이벤트이므로

View Protocol 에 키보드 비활성화 / 키보드 활성화 · 비활성화 감지 기능을 확장(extension)해서 쓰는게 편하다.

 

아래와 같이 필요한 기능을 extension 하면 된다.

 

import SwiftUI

extension View {
    func hideKeyboard() {
            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
    
    func detectKeyboardActivation(activation:@escaping() -> Void){
        NotificationCenter.default.addObserver(
            forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { _ in
            activation()
        }
    }
    
    func detectKeyboardDiablement(disablement:@escaping() -> Void){
        NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { _ in
            disablement()
        }
    }
}

 

extension을 등록했다면 아래와 같이 사용하면 된다.

 

var body: some View {
    VStack{

    }
     .onAppear{
            detectKeyboardActivation{
                print("키보드 활성화 감지")
            }
            
            detectKeyboardDiablement{
                print("키보드 비활성화 감지")
            }
        }
  }