Weekoding

[Swift] TextView PlaceHolder(Custom) 본문

공부 노트(Swift)

[Swift] TextView PlaceHolder(Custom)

Weekoding 2022. 8. 8. 01:41

Placeholder : 자리 표시자.

앱 개발 시 사용자에게 보다 편리한 UX를 제공하기 위해,

Text를 입력할 수 있는 컴포넌트에는 PlaceHolder가 보통 기본 속성으로 포함되어있다.

 

아래와 같은 모양의 UI를 많이 보았을 것이다.

내용을 입력하세요..

 

이렇게 TextField / TextView를 그냥 두기보다, Placeholder를 이용하여 사용자에게 해당 컴포넌트의 역할을 알려주는 것이다.

근데 Swift의 TextView에는 Placeholder가 없다..?🫠

 

공부를 하다가 교묘하게 Placeholder 모양새를 낼 수 있는 방법을 알아내어 포스팅 하게 되었다.

 

 

 

 

Write me !

뚝딱뚝딱 Snapkit으로 UI를 간단하게 구성해보았다.(SnapKit 코딩은 이전 포스팅 참고)

위에 있는 컴포넌트가 TextView, 아래의 컴포넌트가 TextField이다.

TextField는 Placeholder 속성이 존재하여 바로 "Write me"라는 문구를 넣어 주었다.

self.txtField.placeholder = "Write me"

확실히 TextView는 Placeholer로 지시된 바가 없어, 덩그러니 놓여있는 느낌이다.

각 View의 크기는 내가 임의로 지정한 것이다. 이제 Field와 View의 차이점을 살펴보자.

 

 

 

 

 

📂  Before

정리해 보자면 대략 이렇다.

  TextView TextField
공통점  •  Text를 쓰고, 편집할 수 있다.
차이점  • 여러줄 사용 가능
   (줄의 개수 많아지면 자동으로 스크롤 제공)

 • Placeholder 없음
 •한 줄만 사용 가능


 • Placeholder 있음

 

 

⌘ How to Solve?

생각보다 대단한 로직이나 메소드를 사용하진 않는다. 일단 TextView의 Placeholder가 될 초기 값을 설정해주어야 한다.

        //Custom PlaceHolder
        self.txtView.text = "Write me First"
        self.txtView.textColor = .systemGray3

 

해결 방법은 UITextViewDelegate를 이용하는 것이다.

extension ViewController: UITextViewDelegate {
    func textViewDidBeginEditing(_ textView: UITextView) {
        guard txtView.textColor == .systemGray3 else { return }
        txtView.text = nil
        txtView.textColor = .label
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        if(txtView.text == ""){
            txtView.text = "Write me First"
            txtView.textColor = .systemGray3
        }
    }
}

TextView의 Delegate를 상속받은 후, DidBeginEditing / DidEndEditing의 함수를 이용하면 Placeholder 느낌을 낼 수 있다.

조건문이 잘못되면 Text 입력을 마침과 동시에 공백이 되어버린다던가, 글자색이 계속 옅은 색이되는 오류가 날 수 있다.

 

 

 

 

📂  After

제법 그럴싸하다

글자 색상이 살짝 다른 것 빼고는 그럴싸하다고 생각한다!

다른 앱도 TextView를 사용할 때, 이런 식으로 Custom한 Placeholder를 사용하는 것 같다.

 

 

 

📂  전체 코드

import UIKit
import SnapKit

class ViewController: UIViewController{

    let txtView = UITextView()
    let txtField = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .systemBackground

        self.setView()
    }
    
    private func setView(){
        self.setViewStyle()
        [txtView, txtField].forEach( {view.addSubview($0)} )
        
        self.txtView.snp.makeConstraints({
            $0.height.equalTo(150)
            $0.trailing.leading.equalToSuperview().inset(50)
            $0.centerY.equalToSuperview().offset(-50)
        })
        
        self.txtField.snp.makeConstraints({
            $0.height.equalTo(60)
            $0.trailing.leading.equalToSuperview().inset(50)
            $0.top.equalTo(txtView.snp.bottom).offset(30)
        })
    }
    
    private func setViewStyle(){
        self.txtView.delegate = self
        self.txtView.backgroundColor = .systemGray5
        self.txtView.font = .systemFont(ofSize: 20)
        self.txtView.autocapitalizationType = .none //자동 대문자 방지
        self.txtView.layer.cornerRadius = 12
        
        //Custom PlaceHolder
        self.txtView.text = "Write me First"
        self.txtView.textColor = .systemGray3
        
        
        self.txtField.backgroundColor = .systemGray5
        self.txtField.font = .systemFont(ofSize: 20)
        self.txtField.placeholder = "Write me"
        self.txtField.layer.cornerRadius = 12
    }
}

extension ViewController: UITextViewDelegate {
    func textViewDidBeginEditing(_ textView: UITextView) {
        guard txtView.textColor == .systemGray3 else { return }
        
        txtView.text = nil
        txtView.textColor = .label
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        if(txtView.text == ""){
            txtView.text = "Write me First"
            txtView.textColor = .systemGray3
        }
    }
}

 

 

📌  마치며

다른 공부를 하다가 오랜만에 SnapKit을 쓰려고 하니까 머리가 조금씩 고장이 났었다,,

틈틈히 다시 공부 해야지!

 

 

 

오류 및 지적사항은 댓글로 남겨주시면 감사하겠습니다!

 

Comments