Skip to content
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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

Conversation

wjdalswl
Copy link
Member

@wjdalswl wjdalswl commented Jan 2, 2025

📌 Summary

HandyTextField와 HandyTextView 구현했습니다.

✍️ Description

💡 PR Point

🔥 Test

2025-01-02.2.14.01.mov
2025-01-02.2.13.16.mov

@wjdalswl wjdalswl linked an issue Jan 2, 2025 that may be closed by this pull request
1 task
@wjdalswl wjdalswl self-assigned this Jan 2, 2025
Copy link

@chongin12 chongin12 left a 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같은 중요한 컴포넌트라서 코드 리뷰가 조금 길어졌네요..ㅠ 혹시 궁금하신 내용이 있다면 편하게 답변 남겨주세요!!

Comment on lines 17 to 21
@Invalidating(.layout) public var isDisabled: Bool = false {
didSet {
updateState()
}
}

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 요소만 바꾸면 될 것 같아요! 따라서 다음 방법 중 한가지를 추천드릴게요!

  1. @Invalidating(.display) 를 사용하고 draw(_ rect:) 함수를 override하여 updateState() 함수를 그 안에 배치
  2. @Invalidating을 사용하지 않고, didSet만 유지

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 전반적으로 @Invalidating 에 대해 한번씩만 더 고민해주시면 감사하겠습니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇네요! display만 바꾸는 걸로 수정했습니다! 다른 코드들도 한 번씩 확인하고 반영했습니다!

Comment on lines 105 to 108
NotificationCenter.default.addObserver(self,
selector: #selector(textDidChange),
name: UITextView.textDidChangeNotification,
object: nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 코드와 아래 textViewDidChange()가 같은 역할을 하고 있는 것 같아요! (개인적으로 NotificationCenter를 제외시키는 것을 추천드립니다~!)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 삭제했습니다!

Comment on lines 29 to 47
/**
텍스트 뷰의 최소 높이를 설정합니다.
*/
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 }
}

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를 동적으로 조절하기 굉장히 힘들어질 것 같아요.

Copy link
Member Author

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 커스터마이징 제공하는 방식으로 코드 변경했습니다!👍

@wjdalswl wjdalswl added the feat 💜 새로운 기능 구현 label Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat 💜 새로운 기능 구현
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] HandyTextField 추가
2 participants