iOS) UITextField 을 다뤄보자 (테두리/키보드업다운)

2 minute read

내용

  • 텍스트필드 입력 시 테두리 색 변경
  • 텍스트필드 입력 완료 후 키보드 다운 구현
  • 텍스트가 채워지면 특정 버튼 활성화
  • 텍스트필드 선택 후 뷰 터치하면 키보드 다운 구현
  • 텍스트필드 선택 후 뷰 올리기(collectionview 에 inset 부여)

프로젝트를 진행하면서 위와 같이 UITextField 를 구현해야했다. 알아보자!

완성

🖍 테두리 색 변경 / 키보드 업다운 / 채워지면 특정 버튼 활성화

// cardNameTextField.layer.cornerRadius = 10
// 다음과 같이 cornerRadius 를 지정하지 않으면 borderSytle 프로퍼티에 roundedRect 를 주더라도 boderColor 를 주었을 때 각진 모서리를 가진다.

extension FrontCardCreationCollectionViewCell: UITextFieldDelegate {
// ✅ textField 에서 편집을 시작한 후
    func textFieldDidBeginEditing(_ textField: UITextField) {
// 키보드 업
        textField.becomeFirstResponder()
// 입력 시 textField 를 강조하기 위한 테두리 설정
        textField.borderWidth = 1
        textField.borderColor = Colors.white.color
    }

// ✅ textField 에서 편집이 끝난 후(first responder 를 resign 한 후)
    func textFieldDidEndEditing(_ textField: UITextField) {
// 입력 완료시 총 4개의 텍스트필드가 비어있는지 여부를 판단해서 notification 을 보냄.
// 비어있지 않다면 특정 버튼을 활성화 시키는 notification 을 보낸다.
        if cardNameTextField.hasText && userNameTextField.hasText && birthTextField.hasText && mbtiTextField.hasText {
            NotificationCenter.default.post(name: .frontCardtextFieldIsEmpty, object: false)
        } else {
            NotificationCenter.default.post(name: .frontCardtextFieldIsEmpty, object: true)
        }
// 입력 종료시 테두리 없애기
        textField.borderWidth = 0
    }

// ✅ 텍스트필드에 대한 return 버튼 누름처리를 할 것인지 묻는다.(true: 처리O, false: 처리X)
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// 키보드 다운
// resignFirstResponder() 는 first responder 를 포기하는 메서드다. 리턴값이 Bool 이고 기본적으로 true 를 구현한다. 
        return textField.resignFirstResponder()
    }
}

🖍 뷰 터치하면 키보드 다운

// endEditing(_:) : cauese view to resign first responder
let tapGesture = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
self.view.addGestureRecognizer(tapGesture)

🖍 텍스트필드 선택시 키보드 크기만큼 뷰 올리기

// UIResponder.keyboardWillShowNotification : 키보드가 해제되기 직전에 post 된다.
NotificationCenter.default.addObserver(self, selector: #selector(setKeyboardShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
// UIResponder.keyboardWillHideNotificationdcdc : 키보드가 보여지기 직전에 post 된다.
NotificationCenter.default.addObserver(self, selector: #selector(setKeyboardHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)

// ✅ 키보드 업
@objc
func setKeyboardShow(_ notification: Notification) {
    if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardHeight = keyboardFrame.cgRectValue.height
        self.view.frame.origin.y -= keyboardHeight
    }
}

// ✅ 키보드 다운
@objc
private func setKeyboardHide(_ notification: Notification) {
    if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardHeight = keyboardFrame.cgRectValue.height
        self.view.frame.origin.y += keyboardHeight
    }
}

UITextField 가 두개이상일 경우에는 경우의 수가 생긴다.

  • 첫번째 텍스트 필드 선택 → 두번째 텍스트 필드 선택

이런 경우에는 텍스트 필드를 한번 더 선택해서 키보드가 내려가지 않은채로 setKeyboardShow(_:) 메서드가 한번 더 호출된다.

그래서 다음과 같이 구현해보았다.

// 뷰의 초기 y 값을 저장해서 뷰가 올라갔는지 내려왔는지에 대한 분기처리시 사용.
private var restoreFrameYValue = 0.0
restoreFrameYValue = self.view.frame.origin.y

// ✅ 키보드 업
    @objc
    func showKeyboard(_ notification: Notification) {
// 키보드가 내려왔을 때만 올린다.
        if self.view.frame.origin.y == restoreFrameYValue {
            if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
                let keyboardHeight = keyboardFrame.cgRectValue.height
                self.view.frame.origin.y -= keyboardHeight
                print("show keyboard")
            }
        }
    }

// ✅ 키보드 다운
    @objc
    private func hideKeyboard(_ notification: Notification) {
// 키보드가 올라갔을 때만 내린다.
        if self.view.frame.origin.y != restoreFrameYValue {
            if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
                let keyboardHeight = keyboardFrame.cgRectValue.height
                self.view.frame.origin.y += keyboardHeight
                print("hide keyboard")
            }
        }
    }

Categories:

Updated: