-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#21] HandyTextField, HandyTextView 추가 #33
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 요소들을 사용하는 사람 입장에서 커스터마이징이 상당히 난이도가 있어보여요..!
예를 들어 "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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코드 전반적으로 @Invalidating
에 대해 한번씩만 더 고민해주시면 감사하겠습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇네요! display만 바꾸는 걸로 수정했습니다! 다른 코드들도 한 번씩 확인하고 반영했습니다!
NotificationCenter.default.addObserver(self, | ||
selector: #selector(textDidChange), | ||
name: UITextView.textDidChangeNotification, | ||
object: nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 코드와 아래 textViewDidChange()가 같은 역할을 하고 있는 것 같아요! (개인적으로 NotificationCenter를 제외시키는 것을 추천드립니다~!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 삭제했습니다!
/** | ||
텍스트 뷰의 최소 높이를 설정합니다. | ||
*/ | ||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minHeight와 maxHeight는 프로퍼티로 두는 것 보다 HandyTextView를 사용하는 사람이 constraints로 설정한 그대로 따라가는 것도 괜찮을 것 같아요! maxHeight가 지정이 되는 순간 이 TextView를 동적으로 조절하기 굉장히 힘들어질 것 같아요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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