UITextField에 버튼 넣기 (feat. rightView)

SteadySlower·2023년 8월 1일
0

iOS Development

목록 보기
30/38
post-custom-banner

이번 포스팅에서는 UITextField 안에 버튼을 넣어서 isSecureTextEntry를 토글할 수 있는 Text Field를 만들어보겠습니다.

SubView로 넣기?

처음에 딱 떠오르는 생각은 아래처럼 secureButton 객체와 실행하려는 동작은 rx로 구현하고 addSubView를 통해서 구현하는 것입니다.

private let secureButton: UIButton = {
    let button = UIButton()
    button.setImage(UIImage(named: Constant.Image.Eye.closed), for: .normal)
    button.setImage(UIImage(named: Constant.Image.Eye.open), for: .selected)
    return button
}()
private func bind() {
    secureButton.rx.tap
        .asDriver()
        .drive(onNext: { [weak self] in
            self?.secureButton.isSelected.toggle()
            self?.isSecureTextEntry.toggle()
        })
        .disposed(by: disposeBag)
}
addSubview(secureButton)
secureButton.snp.makeConstraints { make in
    make.top.equalToSuperview().offset(15)
    make.bottom.equalToSuperview().offset(-15)
    make.right.equalToSuperview().offset(-15)
    make.width.equalTo(secureButton.snp.height)
}

이 방법의 문제점🚫

하지만 이 방법은 치명적인 단점이 있습니다. UITextField가 FirstResponder인 경우, 즉 TextField 안에 텍스트를 수정하고 있을 때는 UITextField는 자신 내부에서 발생하는 모든 이벤트의 Responder가 됩니다. 따라서 UIButton인 secureButton에는 tap 이벤트가 전달되지 않는 것이죠.

rightView

UITextField에는 rightView라는 속성이 있습니다. 이 부분은 말 그대로 UITextField의 오른쪽 부분에 보여지는 View라는 뜻인데요. (leftView도 있습니다.) 이 rightView에 버튼을 넣게 되면 해당 버튼은 UITextField가 FirstResponder가 되더라도 Event를 전달 받을 수 있습니다. 별개의 View가 아니라 UITextField의 일부가 되기 때문입니다.

또한 rightViewRect라는 메소드를 통해서 rightView의 위치와 크기를 정해 줄 수 있습니다.

rightViewMode = .always
rightView = secureButton
override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
    return CGRect(x: bounds.width - 30, y: 15, width: bounds.height - 30, height: bounds.height - 30)
}

profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 8월 1일

많은 도움이 되었습니다, 감사합니다.

답글 달기