[swift] 스택 뷰에서의 키보드 이벤트 처리 방법

스택 뷰는 사용자 인터페이스 요소를 쉽게 정렬하고 관리할 수 있는 강력한 도구입니다. 하지만 때로는 스택 뷰 안에 있는 텍스트 필드나 텍스트 뷰에서 키보드 이벤트를 처리하기가 어려울 수 있습니다. 이 글에서는 스택 뷰 안에서 키보드 이벤트를 처리하는 방법에 대해 알아보겠습니다.

1. 키보드 이벤트 감지하기

키보드 이벤트를 감지하기 위해서는 NotificationCenter를 사용합니다. 스택 뷰 안에 있는 모든 텍스트 필드와 텍스트 뷰에서 발생하는 키보드 이벤트를 감지하기 위해 NSNotification.Name.UIKeyboardWillShowNSNotification.Name.UIKeyboardWillHide 알림을 관찰합니다.

override func viewDidLoad() {
    super.viewDidLoad()
    
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

@objc private func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        // 키보드가 올라올 때 실행할 코드를 작성합니다.
        // 예: 스크롤 뷰의 컨텐츠 영역 크기를 조정하거나 텍스트 필드를 스크롤하도록 한다.
    }
}

@objc private func keyboardWillHide(notification: NSNotification) {
    // 키보드가 사라질 때 실행할 코드를 작성합니다.
    // 예: 스크롤 뷰의 컨텐츠 영역 크기를 복원한다.
}

2. 스크롤 뷰의 컨텐츠 조정

키보드가 나타났을 때 스크롤 뷰의 컨텐츠를 자동으로 조정하여 텍스트 필드와 텍스트 뷰에 가려지지 않도록 할 수 있습니다. keyboardWillShow 메서드에서 UIScrollView 클래스의 setContentInset 메서드를 사용하여 스크롤 뷰의 컨텐츠 영역을 조정합니다.

@objc private func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
        scrollView.contentInset = contentInset
        scrollView.scrollIndicatorInsets = contentInset
    }
}

@objc private func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}

3. 텍스트 필드와 텍스트 뷰 스크롤하기

키보드가 존재하는 상황에서 텍스트 필드와 텍스트 뷰가 키보드에 의해 가려지는 경우, 사용자가 입력한 내용을 볼 수 있도록 스크롤을 조정해줘야 합니다. 이를 위해 scrollRectToVisible 메서드를 사용하여 텍스트 필드 또는 텍스트 뷰가 특정 위치로 보일 수 있도록 스크롤을 조정합니다.

@objc private func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
        scrollView.contentInset = contentInset
        scrollView.scrollIndicatorInsets = contentInset
        
        if let activeTextField = findActiveTextField(), activeTextField.frame.origin.y + activeTextField.frame.height > scrollView.frame.height - keyboardSize.height {
            let offset = CGPoint(x: 0, y: activeTextField.frame.origin.y + activeTextField.frame.height - scrollView.frame.height + keyboardSize.height)
            scrollView.setContentOffset(offset, animated: true)
        }
    }
}

private func findActiveTextField() -> UITextField? {
    // 스택 뷰 안에서 현재 활성화된 텍스트 필드를 찾는 로직을 작성합니다.
    // 예: 배열로 텍스트 필드들을 관리하고 현재 활성화된 텍스트 필드를 반환
}

@objc private func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}

스택 뷰 안에서 키보드 이벤트를 처리하는 방법에 대해 알아보았습니다. 이제 텍스트 필드와 텍스트 뷰에서도 원활한 키보드 이벤트 처리를 위한 코드를 작성할 수 있을 것입니다.

참고 자료