Edited at

UITextViewへの入力文字を監視し、Viewの高さを動的に変更する with RxSwift

More than 1 year has passed since last update.


概要


イメージ

before
after

before.gif
after.gif


環境


  • Xcode 9.4

  • Swift 4.1

  • RxSwift 4.2

  • RxCocoa 4.2


サンプルリポジトリ


Viewを用意する

ViewController
InputView

スクリーンショット 2018-08-19 21.35.03.png
スクリーンショット 2018-08-19 21.32.11.png


  • ViewControllerの下部にInputViewを配置する


Constraintの設定

スクリーンショット 2018-08-19 21.36.59.png


  • ViewControllerの下部に設定したInputViewに高さのConstraintをつける

  • 実装では、以下のように入力文字に合わせてこのConstraintの値をいじっていくことで、動的に高さを変更させる

viewc.gif


コード


ViewController.swift

import UIKit

import RxSwift
import RxCocoa

class ViewController: UIViewController {

@IBOutlet weak var messageInputView: MessageInputView!
@IBOutlet weak var messageInputViewHeightConstraint: NSLayoutConstraint!

private let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()
setupMessageInputView()
}

private func setupMessageInputView() {
let inputTextViewVerticalMargin: CGFloat = 12.0
messageInputView.inputTextView.rx.text
.asDriver()
.drive(onNext: { [weak self] _ in
// テキスト入力されるたびに呼ばれる (削除でも)
guard let height = self?.messageInputView.inputTextView.contentSize.height else { return }
let inputTextViewHeight = height + inputTextViewVerticalMargin
self?.messageInputViewHeightConstraint.constant = inputTextViewHeight
self?.view.setNeedsLayout()
self?.view.layoutIfNeeded()
})
.disposed(by: disposeBag)
}

}



  • 上記の実装で高さを動的に変更できるようになる

  • しかし、高さの制限がないので下記のGIFのように画面の外までUIが伸びてしまう

hei.gif


  • 次に、高さの制限をする


    • といっても実装は簡単で、あるラインを決めてそれ以上の値になったら変更をさせないようにすればよい




ViewController.swift


let inputTextViewMaxHeight: CGFloat = 100.0 // New Line
let inputTextViewVerticalMargin: CGFloat = 12.0
messageInputView.inputTextView.rx.text
.asDriver()
.drive(onNext: { [weak self] _ in
guard let height = self?.messageInputView.inputTextView.contentSize.height else { return }
let inputTextViewHeight = height + inputTextViewVerticalMargin
if inputTextViewMaxHeight > inputTextViewHeight { // New Line
self?.messageInputViewHeightConstraint.constant = inputTextViewHeight
} // New Line
self?.view.setNeedsLayout()
self?.view.layoutIfNeeded()
})
.disposed(by: disposeBag)


Notes


  • 高さの制限を変更したい場合は、 inputTextViewMaxHeight の値を変更しよう