9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iMessageの入力UIのようなキーボードの表示と連動するUIを作る with RxSwift, RxKeyboard

Last updated at Posted at 2018-08-16

概要

  • iMessage, LINEのようなテキスト入力UIでキーボードの表示に合わせて位置が動くViewを作る

イメージ

textinput.gif

サンプルリポジトリ

環境

  • Xcode 9.4
  • Swift 4.1
  • RxSwift 4.2
  • RxCocoa 4.2
  • RxKeyboard 0.8.3

簡単概要

  • RxKeyboardライブラリを使ってキーボードの高さを取得、テキスト入力UIのBottomLayoutConstraintに反映させる

ライブラリの導入

Podfile
  pod 'RxSwift'
  pod 'RxCocoa'
  pod 'RxKeyboard'
  pod 'RxOptional'

UIを用意する

ViewController(水色のところにテキスト入力UIを配置) テキスト入力UIView
スクリーンショット 2018-08-17 1.08.05.png スクリーンショット 2018-08-17 1.08.21.png

ViewController

ViewController.swift
import UIKit
import RxSwift
import RxCocoa
import RxKeyboard

class ViewController: UIViewController {

    @IBOutlet weak var messageInputView: MessageInputView!
    @IBOutlet weak var messageInputViewBottomConstraint: NSLayoutConstraint!
    
    private let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupMessageInputView()
    }

    private func setupMessageInputView() {
        RxKeyboard.instance.visibleHeight
            .drive(onNext: { [weak self] keyBoardHeight in
                self?.messageInputViewBottomConstraint.constant = -keyBoardHeight
                self?.view.layoutIfNeeded()
            })
            .disposed(by: disposeBag)
    }
}

ViewController.xib

z.gif

@IBOutlet weak var messageInputViewBottomConstraint: NSLayoutConstraint!
  • ViewControllerのconstraintとswiftコードを繋ぐ

簡単解説

        // RxKeyboard.instance <- シングルトンインスタンス
        RxKeyboard.instance.visibleHeight
            .drive(onNext: { [weak self] keyboardHeight in
                // keyboardの高さが変わるたびに呼ばれる
                self?.messageInputViewBottomConstraint.constant = -keyboardHeight
                // Viewの更新
                self?.view.setNeedsLayout()
                self?.view.layoutIfNeeded()
            })
            .disposed(by: disposeBag)

他にも

  • visibleHeightはキーボードが非表示の時に0を流しますが、 スクロールビューのcontentOffsetを調整する場合は向いていないので、0を流さないwillShowVisibleHeight を使うと良いらしいです :muscle:
// contentOffset
RxKeyboard.instance.willShowVisibleHeight
  .drive(onNext: { keyboardVisibleHeight in
    scrollView.contentOffset.y += keyboardVisibleHeight
  })
  .disposed(by: disposeBag)
  • 他にもkeyboardのframeを取得することもできるみたい(何に使うんだろう? :thinking:

more detail :arrow_down:

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?