概要
- UITextViewへの文字入力を監視し、Viewの高さを変更させる
- 過去の記事(iMessageの入力UIのようなキーボードの表示と連動するUIを作る with RxSwift, RxKeyboard)の開発の延長という体で書いてます
イメージ
before | after |
---|---|
環境
- Xcode 9.4
- Swift 4.1
- RxSwift 4.2
- RxCocoa 4.2
サンプルリポジトリ
Viewを用意する
ViewController | InputView |
---|---|
- ViewControllerの下部にInputViewを配置する
Constraintの設定
- ViewControllerの下部に設定したInputViewに高さのConstraintをつける
- 実装では、以下のように入力文字に合わせてこのConstraintの値をいじっていくことで、動的に高さを変更させる
コード
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が伸びてしまう
- 次に、高さの制限をする
- といっても実装は簡単で、あるラインを決めてそれ以上の値になったら変更をさせないようにすればよい
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
の値を変更しよう