본문 바로가기
Xcode/IOS

IOS) Custom KeyBoard 다루기

by 후르륵짭짭 2020. 7. 14.
728x90
반응형

완성 본

안녕하세요 후르륵짭짭 입니다!

이번에는 textField에 나오는 KeyBoard를 다뤄 볼려고 합니다!

textField를 누르면 키보드가 올라오는데, 그것이 항상 뷰를 가려버리져,,,

그래서 많은 깊은 빡침을 느껴 보셨을 겁니다.

이제 그 문제를 해결 해 보려고 합니다!

 

** 텍스트 필드 생성 ** 

뷰와 텍스트 필드를 생성하고 아울렛으로 연결 해주세요!

    @IBOutlet var MainView: UIView!
    @IBOutlet weak var idTextField: UITextField!
    @IBOutlet weak var passTextField: UITextField!
	//연결용    
    var ActivateTextfield : UITextField!

이렇게 연결해주시고 여분의 UITextField를 생성해주세요.

이것은 텍스트가 여러개 있을 때 사용해주면 좋습니다.

 

** UITextFieldDelegate를  받는다 **

UITextFieldDelegate를 뷰 컨트롤러에 상속? 받아주세요!

그리고 각 텍스트 필드이 delgate를  연결시켜주세요!

extension ViewController : UITextFieldDelegate {
    
    func setTextfiledDelegate(){
        idTextField.delegate = self
        passTextField.delegate = self
        
        //태그는 확인용 입니다.
        idTextField.tag = 1
        passTextField.tag = 2
        
    }
    
 }

이렇게 delegate를 연결 시켜주고 반드시 viewDidLoad()에서 불러와 주세요!

그리고 나서 textFieldDidBeginEditing 함수를 불러주세요!

    func textFieldDidBeginEditing(_ textField: UITextField) {
        ActivateTextfield = textField
        print(ActivateTextfield.tag)
    }

이 함수는 텍스트 필드를 누를경우에 반응하는 함수는 입니다.

텍스트 필드가 두개 이기 때문에 지금 반응하는 텍스트 필드를 ActivateTextField에 넣어주게 됩니다.

 

** Done 버튼을 누르면 키보드 내려버리기 ** 

Done 버튼을 누르면 키보드를 내려보내야져

그래서 필요한 것이 textFieldShouldReturn 코드 입니다

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        ActivateTextfield.resignFirstResponder()
        
        return true
    }

이 코드는 텍스트 필드의 return 버튼을 눌렀을 때 어떻게 반응해줄 것인지를 정의 하는 함수 입니다.

무시할려면 false를 반환 해주고 반응 해줄려면 true를 반환 해주세요.

그리고 이 함수 내부에 현재 텍스트 필드를 담고 있는 ActivateTextField의 resginFirstResponder()를  적어주세요!

 

** resignFirstResponder??? **

resign : 사직하다

First : 첫번째

Responder : 반응하는 것

말 그대로 첫번째 반응하는 것을 사직하다(제거하다)로 해석하면 됩니다.

스마트폰 화면의 모든 것은 많은 responder와 request로 이뤄어져 있습니다.

그 중 텍스트 필드를 누르면 키보드가 나오죠. 그리고 이 키보드가 화면의 FirstResponder가 됩니다.

즉, 화면상에 첫번째 responder인 키보드를 제거하겠다!

이 말 입니다.

 

** 빈 화면을 누르면 키보드 내리기 **

이제 아무 빈 화면을 누르면 화면을 내리도록 해야합니다.

간단하게 해결 할 수 있습니다.

Button을 전체 화면에 놓아도 되고 아니면 저 처럼 tapGesture를 해도 됩니다.

그래서 아래 코드 처럼 그냥 resignFirstResponder 해주면 됩니다.

아니면 현재 뷰의 Editing을 끝마치는 함수를 넣어주면 됩니다. (self.view.endEditing(true))

    @IBAction func tapGesture(_ sender: Any) {
        
        if ActivateTextfield == nil {
            return
        }
        
        //self.view.endEditing(true)
        ActivateTextfield.resignFirstResponder()
        
      }

 

** 키보드가 나올 때 화면 가리기 문제 해결하기 **

 키보드가 올라왔을 때, 내려 갔을 때의 동작은 노티피케이션으로 이뤄어져 있습니다.

따라서 다음과 같이 코드를 적어주세요. 그리고 viewDidLoad()에 넣어줘야합니다.

    func FuncaddObservser(){
        NotificationCenter.default.addObserver(self, selector: #selector(KeyBoardwillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
               
        NotificationCenter.default.addObserver(self, selector: #selector(KeyBoardwillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    }

이 두 노티피케이션의 차이는 keyboardWillShowNotification , keyboardWillHideNotification 이 둘 뿐 입니다.

UIResponder안에 키보드 노티피케이션이 존재한다고 생각하면 됩니다.

 

그리고 이제 #selector()안에 objc 함수를 정의해줘야합니다.

    @objc func KeyBoardwillShow(_ noti : Notification ){

        view.transform = CGAffineTransform(translationX: 0, y: -50)
        
    }
    
    @objc func KeyBoardwillHide(_ noti : Notification ){
        
        view.transform = .identity
        
    }

키보드가 올라왔을 때의 행동 과 키보드가 내려갈 때의 행동을 취해줘야합니다.

다양한 방법이 존재하는데, 저는 view의 transform을 사용했습니다.

 

** SearchBar의 키보드 내리기 **

 TextField는 아니지만 SearchBar를 내리는 방법에 대해서 까지 적어보도록 하겠습니다.

SearchBar도 텍스트 필드와 마찬가지 delegate를 받아야합니다.

class SearchViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setDelegate()
        // Do any additional setup after loading the view.
    }
   
}

extension SearchViewController : UISearchBarDelegate {
    
    func setDelegate(){
        searchBar.delegate = self
    }
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
    }
    
}

따라서 이렇게 UISearchBarDelegate를 받아서 현재 사용하고자 하는 searchBar와 연결시켜주고

searchBarSearchButtonClicked 함수를 사용한 다음 위에서 설명한

resignFirstResponder()를 사용해주세요!

 

지금까지 키보드를 다루는 아주아주 큰 도움이 될 수도 있고 

아닐 수도 있는 기초적인 것을 배워봤습니다.

모두 즐코즐코 하세요!!

 

** 전체 코드 ** 

- 첫번째 화면 -

class ViewController: UIViewController {

    @IBOutlet var MainView: UIView!
    @IBOutlet weak var idTextField: UITextField!
    @IBOutlet weak var passTextField: UITextField!
    
    var ActivateTextfield : UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        setTextfiledDelegate()
        FuncaddObservser()
    }
    
    @IBAction func tapGesture(_ sender: Any) {
        
        if ActivateTextfield == nil {
            return
        }
        
        //self.view.endEditing(true)
        ActivateTextfield.resignFirstResponder()
        
      }
    
    @IBAction func nextPage(_ sender: UIButton) {
        
        guard let id = idTextField.text , id.isEmpty == false , let pass = passTextField.text , pass.isEmpty == false else  {
            return
        }
        
        guard let vc = storyboard?.instantiateViewController(withIdentifier: "SearchVC") as? SearchViewController else{return}
        
        vc.modalPresentationStyle = .overFullScreen
        vc.modalTransitionStyle = .crossDissolve
        
        present(vc, animated: true, completion: nil)
    }


}

extension ViewController : UITextFieldDelegate {
    
    func setTextfiledDelegate(){
        idTextField.delegate = self
        passTextField.delegate = self
        
        idTextField.tag = 1
        passTextField.tag = 2
        
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        ActivateTextfield = textField
        print(ActivateTextfield.tag)
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        ActivateTextfield.resignFirstResponder()
        
        return true
    }
    
    func FuncaddObservser(){
        NotificationCenter.default.addObserver(self, selector: #selector(KeyBoardwillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
               
        NotificationCenter.default.addObserver(self, selector: #selector(KeyBoardwillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    @objc func KeyBoardwillShow(_ noti : Notification ){

        view.transform = CGAffineTransform(translationX: 0, y: -50)
        
    }
    
    @objc func KeyBoardwillHide(_ noti : Notification ){
        
        view.transform = .identity
        
    }
    
}

 

- 두번째 화면 -

class SearchViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setDelegate()
        // Do any additional setup after loading the view.
    }
    
    @IBAction func disMissBtn(_ sender: UIButton) {
        
        dismiss(animated: true, completion: nil)
        
    }

}

extension SearchViewController : UISearchBarDelegate {
    
    func setDelegate(){
        searchBar.delegate = self
    }
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
    }
    
}
728x90
반응형

댓글