ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UITextField clear button custom
    iOS 2021. 10. 16. 23:48

    UITextField 에서는 기본적으로 clear 버튼을 제공하는데요,

    이걸 커스텀 하려면 어떻게 하는지, 이때 또 어떤 문제가 있었는지 알아보겠습니다 :)

     


     

    기본 clear button

    우선 기본적인 clear 버튼은 clearButtonMode를 통해 만들어줄 수 있습니다.

    textfield.clearButtonMode = .whileEditing

     

    이렇게 4가지 모드가 있는데 각각은 보시면 아시겠죠??

    아무튼 이걸 설정해주면 이렇게 clear 버튼이 나타나고, 버튼을 눌러 clear까지 알아서 해줄 수가 있습니다.

     

    clear button custom

    문제는 저 clear 버튼을 커스텀 할 수가 없다는 겁니다.. (아니 🍎 쓰는김에 좀 더 쓰지...)
    제 문제는 저 어두운 배경에서 clear 이 너무 안 보인다는 거 였어요... 

    일단 결론부터 말씀드리면 저 버튼을 직접 건드릴 생각은 하면 안 되고 textField의 rightView를 직접 붙여줘서 처리해줘야 합니다.

    그래도 다행히 rightView도 rightViewMode를 제공해서 clear 버튼처럼 어느 상황에 나타날지 처리해줄 수가 있어요!
    대신, clear 기능은 직접 구현을 해야합니다... ㅠ

    rightView는 overlayView를 지정해주는건데요, clearButton은 따로 지정해주기 전에 미리 내장되어있는 overlayView 에요,
    그래서 rightView를 지정하고, rightViewMode를 통해서 rightView로 overlayView를 바꿔주면
    기존에 내장되어 있던 clearButton(overlayView)은 나타나지 않습니다.

     

    구현

    큰 원리는 이렇구요,

    저는 다른 cancel 이미지를 가지는 버튼을 만들어서 rightView에 붙이는 방식으로 처리를 했습니다.
    이 부분은 말 그대로 버튼이나 원하는 뷰를 붙여서 만드는 거라서 원하는 형태로 커스텀 하시면 될 것 같아요.

    저는 extension으로 이렇게 처리해봤어요

    import UIKit
    
    extension UITextField {
        
        func setClearButton(with image: UIImage, mode: UITextField.ViewMode) {
            let clearButton = UIButton(type: .custom)
            clearButton.setImage(image, for: .normal)
            clearButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
            clearButton.contentMode = .scaleAspectFit
            clearButton.addTarget(self, action: #selector(UITextField.clear(sender:)), for: .touchUpInside)
            self.rightView = clearButton
            self.rightViewMode = mode
        }
        
        @objc
        private func clear(sender: AnyObject) {
            self.text = ""
        }
    }

     

    문제

    여기서 한 가지 사소한 문제가 발생하는데요, 기존에 clear 버튼의 동작과 조금 다르게 동작 하는 부분이 있습니다... ㅠㅠ

    기존에 clear버튼은 whileEditing 모드일 때, textField의 text가 비어있을 때 clear 버튼이 보이지 않는데요, 
    rightView는 whileEditing 모드여도, 그냥 firstResponder만 되어도 rightView가 나타납니다.
    물론 clear를 해도 그대로 남아있죠...

    사실 큰 문제는 아니라 그대로 써도 되지만.. 기존 clear 버튼처럼 동작하게 하기 위해 다음과 같이 추가해봤습니다.
    결국 text가 비어있는지 계속 체크해서 확인해주는 방식이에요. (이게 최선인지는 모르겠습니다,,,)

    import UIKit
    
    extension UITextField {
        
        func setClearButton(with image: UIImage, mode: UITextField.ViewMode) {
            let clearButton = UIButton(type: .custom)
            clearButton.setImage(image, for: .normal)
            clearButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
            clearButton.contentMode = .scaleAspectFit
            clearButton.addTarget(self, action: #selector(UITextField.clear(sender:)), for: .touchUpInside)
            self.addTarget(self, action: #selector(UITextField.displayClearButtonIfNeeded), for: .editingDidBegin)
            self.addTarget(self, action: #selector(UITextField.displayClearButtonIfNeeded), for: .editingChanged)
            self.rightView = clearButton
            self.rightViewMode = mode
        }
        
        @objc
        private func displayClearButtonIfNeeded() {
            self.rightView?.isHidden = (self.text?.isEmpty) ?? true
        }
        
        @objc
        private func clear(sender: AnyObject) {
            self.text = ""
            sendActions(for: .editingChanged)
        }
    }

     

    조금이라도 도움이 되셨다면 좋겠네요.

    감사합니다 :)

    댓글

Designed by Tistory.