[#21] HandyTextField, HandyTextView 추가#33
Conversation
There was a problem hiding this comment.
이 요소들을 사용하는 사람 입장에서 커스터마이징이 상당히 난이도가 있어보여요..!
예를 들어 "textField의 text가 특정 정규표현식을 만족하지 않는다면 isNegative = false로 바꾸고 싶어" 라는 명세가 주어진다면 어떤 식으로 HandyTextFieldView를 활용할 수 있을까요?
-> 우선 delegate 지정은 HandyTextFieldView.textField으로 해야 하구요, 이렇게 되면 기존에 채택된 delegate들은 사용할 수 없어요.
-> 이러면 addTarget이나 NotificationCenter를 사용해야 할 것 같습니다. 사용해야 하는 메소드가 많아지면 많아질수록 메모리에 큰 영향을 끼칠 수 있을 것 같아요.
따라서 새로운 Delegate를 선언하여 커스터마이징을 제공하는 방법은 어떠신가요? 텍스트가 변할 때, 입력을 시작할 때, 입력을 마칠 때, (스크롤이 있다면) 스크롤 할 때 등등 유용하게 쓰일 것 같은 메소드들을 미리 정의해서 제공하면 라이브러리를 사용하는 입장에서 훨씬 편할 것 같아요!
TextField나 TextView같은 중요한 컴포넌트라서 코드 리뷰가 조금 길어졌네요..ㅠ 혹시 궁금하신 내용이 있다면 편하게 답변 남겨주세요!!
| @Invalidating(.layout) public var isDisabled: Bool = false { | ||
| didSet { | ||
| updateState() | ||
| } | ||
| } |
There was a problem hiding this comment.
layout을 무효화(Invalidating) 시키면 setNeedsLayout()가 불리게 됩니다. (출처)
setNeedsLayout()은 다음 UI 업데이트 사이클에 layoutSubviews() 함수를 부르게 해줍니다.
그래서, @Invalidating(.layout) 에 따라서 다시 subview들을 배치해야 하는 상황일 때 추가적인 작업은 layoutSubviews() 을 오버라이딩 해서 넣는거죠.
isDisabled는 (제가 생각했을 때) subview들과는 관계가 없고(subview들을 재배치할 필요는 없고), Color 등 display 요소만 바꾸면 될 것 같아요! 따라서 다음 방법 중 한가지를 추천드릴게요!
@Invalidating(.display)를 사용하고draw(_ rect:)함수를 override하여updateState()함수를 그 안에 배치@Invalidating을 사용하지 않고, didSet만 유지
There was a problem hiding this comment.
코드 전반적으로 @Invalidating 에 대해 한번씩만 더 고민해주시면 감사하겠습니다!
There was a problem hiding this comment.
그렇네요! display만 바꾸는 걸로 수정했습니다! 다른 코드들도 한 번씩 확인하고 반영했습니다!
| NotificationCenter.default.addObserver(self, | ||
| selector: #selector(textDidChange), | ||
| name: UITextView.textDidChangeNotification, | ||
| object: nil) |
There was a problem hiding this comment.
이 코드와 아래 textViewDidChange()가 같은 역할을 하고 있는 것 같아요! (개인적으로 NotificationCenter를 제외시키는 것을 추천드립니다~!)
| /** | ||
| 텍스트 뷰의 최소 높이를 설정합니다. | ||
| */ | ||
| public var minHeight: CGFloat? { | ||
| didSet { | ||
| guard let minHeight = minHeight else { return } | ||
| textView.snp.updateConstraints { | ||
| $0.height.greaterThanOrEqualTo(minHeight) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| 텍스트 뷰의 최대 높이를 설정합니다. | ||
| */ | ||
| public var maxHeight: CGFloat? { | ||
| get { return textView.maxHeight } | ||
| set { textView.maxHeight = newValue } | ||
| } |
There was a problem hiding this comment.
minHeight와 maxHeight는 프로퍼티로 두는 것 보다 HandyTextView를 사용하는 사람이 constraints로 설정한 그대로 따라가는 것도 괜찮을 것 같아요! maxHeight가 지정이 되는 순간 이 TextView를 동적으로 조절하기 굉장히 힘들어질 것 같아요.
There was a problem hiding this comment.
HandyTextView의 minHeight와 maxHeight 없애고, HandyBaseTextView의 maxHeight는 남겨두었어요!
defaultTextView.snp.makeConstraints {
$0.top.equalToSuperview().offset(100)
$0.horizontalEdges.equalToSuperview().inset(20)
$0.height.lessThanOrEqualTo(100)
$0.height.greaterThanOrEqualTo(60)
}사용자가 이런식으로 사용했을때 60 높이부터 시작하고, 입력한 만큼 늘어나다가 100에서 높이 증가를 멈춰주기 위해.
lessThanOrEqualTo 에 넣어준 값을 HandyBaseTextView의 최대 높이로 설정해주었습니다!
HandyTextView 자체는 maxHeight를 가지고 있지 않도록 해서, 사용하는 사람이 constraints로 설정한 그대로 따라가도록 했습니다!
또한, Delegate 커스터마이징 제공하는 방식으로 코드 변경했습니다!👍
📌 Summary
HandyTextField와 HandyTextView 구현했습니다.
✍️ Description
💡 PR Point
🔥 Test
2025-01-02.2.14.01.mov
2025-01-02.2.13.16.mov