생성일: 2022년 1월 29일 오전 1:06
⇒ 이를 위해 InputTextView.swift 파일을 생성하고 해당 텍스트 뷰는 UploadPostController.swift에서 생성하여 사용하였다.
import UIKit
class UploadPostsController: UIViewController {
//MARK: - Properties
private lazy var captionTextView: InputTextView = {
let tv = InputTextView()
tv.placeholderText = "Enter caption..."
tv.font = UIFont.systemFont(ofSize: 16)
tv.delegate = self
return tv
}()
// 입력한 글자수를 보여주는 Label
private let characterCountLabel: UILabel = {
let label = UILabel()
label.textColor = .lightGray
label.font = UIFont.systemFont(ofSize: 14)
label.text = "0/100"
return label
}()
... 중략 ...
//MARK: - Helpers
// 100글자 이상 입력하면 넘긴 부분 만큼 지우기
func checkMaxLength(_ textView: UITextView) {
if (textView.text.count) > 100 {
textView.deleteBackward()
}
}
}
//MARK: - UITextViewDelegate
// 텍스트 뷰가 변화하면 이를 트래킹하여 입력한 글자 수를 화면에 띄우도록 한다. 이를 위해 UITextViewDelegate를 불러온다.
extension UploadPostsController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
checkMaxLength(textView)
let count = textView.text.count
characterCountLabel.text = "\(count)/100"
}
}
import UIKit
/// placeholder를 포함한 텍스트 뷰
class InputTextView: UITextView {
//MARK: - Properties
var placeholderText: String? {
didSet { placeholderLabel.text = placeholderText }
}
private let placeholderLabel: UILabel = {
let label = UILabel()
label.textColor = .lightGray
return label
}()
//MARK: - Lifecycle
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
addSubview(placeholderLabel)
placeholderLabel.anchor(top: topAnchor, left: leftAnchor, paddingTop: 6, paddingLeft: 6)
// 텍스트 뷰에 변화가 생기는 것을 트래킹하여 placeholder 제거하기
NotificationCenter.default.addObserver(self, selector: #selector(handleTextDidChange), name: UITextView.textDidChangeNotification, object: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: - Actions
@objc func handleTextDidChange() {
// 텍스트뷰가 비어있으면 placeholder가 보여지게하고 글씨가 한개라도 있다면 placeholder 숨기기
placeholderLabel.isHidden = !text.isEmpty
}
}
InputTextView는 내부적으로 위와 같이 구현한다.
텍스트 뷰 안의 placeholder가 글자가 입력되면 사라지도록 하는 로직을 위해 InputTextView를 트래킹하도록 클래스 내부에 addObserver 를 추가하였는데 이번에 구현한 텍스트 뷰를 사용하는 UploadPostController에서도 해당 텍스트 뷰를 계속 트래킹하기 위해 UITextViewDelegate 프로토콜과 textViewDidChange() 함수를 사용하였다.
⇒ 이중으로 트래킹 하는 것이기 때문에 비효율적이지 않느냐는 의문점이 생김
⇒ 실제로 InputTextView 내부의 addObserver를 없애고 해당 텍스트 뷰를 생성하여 사용하는 외부의 컨트롤러의 textViewDidChange()에서 텍스트 뷰의 글자가 0개가 되면 placeholder를 hidden하도록 설정이 가능하다. (물론 placeholderLabel을 private로 설정하면 안된다.)
⇒ 하지만 굳이 내부와 외부에서 트래킹하도록 구현한데에는 이유가 있다.