본문 바로가기

프로그래밍/iOS,macOS

UITextView 자동 높이

특정 사이즈까지는 높이가 커지다가 해당 사이즈 부터는 스크롤로 전환

초기에는 사이즈가 증가해야 하기에 텍스트뷰의 isScrollEnabled = false 로 설정
높이 제약을 특정 사이즈 이하(lessThanOrEqual)로 설정

let textView: UITextView = .init()

func setup() {
    .
    .
   textView.isScrollEnabled = false
    .
    .
   addSubview(textView)
}

func setupLayout() {
   textView.translatesAutoresizingMaskIntoConstraints = false
   NSLayoutConstraint.activate([
      textView.heightAnchor.constraint(lessThanOrEqualToConstant: 70),
      textView.topAnchor.constraint(equalTo: topAnchor, constant: 0),
      textView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0),
      textView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0),
      textView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0),
   ])
}

delegate 나 rx 로 textview의 didChange 이벤트에서
contentSize가 특정 사이즈 이상인 경우 isScrollEnabled = true 로 변경

func bind() {
   textView.rx
      .didChange
      .subscribe(onNext: { [weak self] in
      	guard let self = self else { return }
        let size = CGSize(width: self.textView.frame.width, height: .infinity)
        let estimatedSize = self.textView.sizeThatFits(size)
        let isMaxHeight = estimatedSize.height >= 70
        
        guard let isMaxHeight != self.textView.isScrollEnabled else { return }
        self.textView.isScrollEnabled = isMaxHeight
        self.textView.reloadInputViews()
        self.setNeedsUpdateConstraints()
      })
      .disposed(by: disposeBag)
}

 

textView.contetSize.height 에도 높이가 변경되는데, 이 값은 갱신 시점의 문제인지 가끔 이전 값이나 요상한 값이 설정되어 sizeThatFits을 사용.