Open-source project
RxSwiftCommunity/RxKeyboard avatar
RxSwiftCommunity/RxKeyboard

RxKeyboard for reactive iOS keyboard layout handling

Reactive Keyboard in iOS

1,602 stars176 forksSwiftMIT

At a glance

What is it?
RxKeyboard exposes keyboard frame and visible-height values as RxSwift Drivers for iOS view and UIScrollView updates. It is aimed at RxSwift applications that need keyboard-aware layouts, including interactive dismissal behavior.
Who is it for?
RxKeyboard suits iOS developers already using RxSwift who want keyboard state delivered through Drivers for scroll view insets, offsets, and toolbar movement. It is a poor fit for UIKit code without RxSwift or for projects needing undocumented cross-platform support.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 121 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Where RxKeyboard Fits in an iOS UI

RxKeyboard addresses a focused UIKit problem: keyboard presentation changes the usable area of an iOS screen, and several interface elements need that state. Text fields, scroll views, toolbars, and custom content containers can require different reactions. RxKeyboard turns keyboard state into values that can be observed through RxSwift rather than requiring each screen to manage keyboard notifications independently.

The intended audience is narrow and technical. It makes sense for an iOS codebase that already uses RxSwift and RxCocoa, because the library exposes `Driver` streams and its examples subscribe with `drive(onNext:)`. The documented platform requirements are Swift 5.1 and iOS 9 or later, while the declared dependencies are RxSwift 6.0 or later and RxCocoa 6.0 or later.

The library does not arrange a view hierarchy or resolve content overlap by itself. It supplies keyboard measurements. Developers still choose what to adjust, such as a `UIScrollView` content inset or a toolbar constraint. This separation makes the API small enough to fit different layout systems, but it also means the application remains responsible for producing a correct interface after every emitted value.

The Three RxKeyboard Driver Signals

RxKeyboard provides three keyboard-related signals through `RxKeyboard.instance`: `frame`, `visibleHeight`, and `willShowVisibleHeight`. The distinction matters because their emission semantics match different layout tasks rather than offering interchangeable aliases.

`frame` represents the keyboard frame. A subscriber can use the complete geometry when positioning depends on more than the vertical obstruction. The README states that subscribing to `RxKeyboard.instance.frame` observes keyboard frame changes, but it does not document a detailed sequence of notification handlers, coordinate-space conversions, or initial-emission behavior. Those implementation details should therefore be checked in source when they affect a particular UIKit integration.

`visibleHeight` emits the keyboard height when the keyboard is visible and `0` when it is not. This is the most direct signal for maintaining a bottom inset or moving a toolbar. `willShowVisibleHeight` follows the same visible-height concept but emits only when the keyboard is about to show. The README presents it as useful for adjusting scroll view content offset. The distinction prevents an application from repeatedly adding height on every frame or visibility update, although it also means this signal should not be selected merely because visible height sounds sufficient.

All three are exposed as RxSwift `Driver` traits. The documented examples attach each subscription to a `disposeBag`, so lifecycle ownership remains part of the consuming screen's reactive code.

Installing RxKeyboard with CocoaPods

The README documents CocoaPods installation, which is the clearest consumer setup for a new application. Add RxKeyboard to the application's `Podfile` and resolve the pods from the project directory. The repository also lists Carthage configuration, but its supported entries are old binary releases tied to specified Xcode and Swift toolchains. Those entries do not establish compatibility with the current Swift 5.1 and RxSwift 6 requirements stated by the README.

This installation uses the exact package declaration documented by the project:

ruby
pod 'RxKeyboard'

After adding the declaration, the README does not provide application-specific `pod install` or import commands, so those should follow the surrounding application's existing CocoaPods workflow rather than be inferred here.

Swift Package Manager appears in the contribution instructions, but the README does not document adding RxKeyboard as a package dependency in a consumer project. It only gives the following command for generating an Xcode project during development:

console
$ swift package generate-xcodeproj

The repository layout includes `Package.swift`, `Package.resolved`, and source directories, yet the documented installation section does not present a consumer-facing Swift Package Manager procedure. That omission is significant for teams selecting a dependency manager. CocoaPods is explicitly supported. Swift Package Manager installation should be verified against the package manifest before being selected as the integration path.

A First RxKeyboard Subscription

The shortest documented first use subscribes to the keyboard frame stream through the singleton. The screen needs an existing `disposeBag`, as used in the README example, so the subscription is released with that view's reactive lifecycle. The callback receives a `CGRect` and prints it in the documented example.

swift
RxKeyboard.instance.frame
  .drive(onNext: { frame in
    print(frame)
  })
  .disposed(by: disposeBag)

This code establishes the central access pattern: obtain `RxKeyboard.instance`, choose a signal, use `drive(onNext:)`, and attach the result to `disposeBag`. The README does not show the import declarations needed in a standalone file, so the example should be added to a target that already has RxSwift, RxCocoa, and RxKeyboard available.

For a more practical first use, `visibleHeight` can update the bottom inset of a `UIScrollView`. According to the README, the emitted value becomes `keyboardVisibleHeight`, which the example writes directly to `contentInset.bottom`:

swift
RxKeyboard.instance.visibleHeight
  .drive(onNext: { [scrollView] keyboardVisibleHeight in
    scrollView.contentInset.bottom = keyboardVisibleHeight
  })
  .disposed(by: disposeBag)

This is a direct adaptation rather than a built-in scrolling policy. It does not decide whether the field is visible, scroll to a selected text input, or handle safe areas. Those behaviors are outside what the README describes.

Scroll View and Toolbar Adaptation Choices

RxKeyboard offers separate examples for content inset, content offset, and toolbar placement. These examples are better understood as patterns for choosing the correct signal than as a universal keyboard-avoidance controller.

For content inset, `visibleHeight` continuously represents the keyboard obstruction or zero. For content offset, `willShowVisibleHeight` is used to add the height once when the keyboard is about to appear:

swift
RxKeyboard.instance.willShowVisibleHeight
  .drive(onNext: { [scrollView] keyboardVisibleHeight in
    scrollView.contentOffset.y += keyboardVisibleHeight
  })
  .disposed(by: disposeBag)

That offset example does not contain logic to reverse or recalculate the adjustment when the keyboard hides. The README presents it as a targeted technique, not a complete managed scroll view. Teams with complex forms may need more state than this sample provides.

A toolbar can instead be moved by frame or constrained through Auto Layout. The non-Auto Layout version calculates a Y origin using the containing view and keyboard height. The Auto Layout version updates the bottom constraint:

swift
RxKeyboard.instance.visibleHeight
  .drive(onNext: { [toolbarBottomConstraint] keyboardVisibleHeight in
    toolbarBottomConstraint.constant = -1 * keyboardVisibleHeight
  })
  .disposed(by: disposeBag)

The README also says that real applications should use `setNeedsLayout()` and `layoutIfNeeded()` inside an animation block and points to `Example/Sources/ViewControllers/MessageListViewController.swift` for an example. The short snippets omit that step, so copying them literally can produce less polished motion than the linked example. RxKeyboard is also documented as working with `UIScrollViewKeyboardDismissMode.interactive`, which makes the visible-height signal relevant to continuously changing keyboard presentation.

RxSwift Drivers Compared with Manual Notification Handling

The main alternative is registering for keyboard notifications directly through UIKit and translating each notification into layout updates. Both approaches can ultimately adjust the same `UIScrollView` property or Auto Layout constraint, but they impose different state-management choices.

Manual notification handling gives an application explicit access to individual UIKit events and keeps the integration independent of RxSwift. It can be appropriate in a UIKit screen with no reactive architecture, or when notification payload fields and timing need direct control. The cost is that every relevant screen must implement observation, cleanup, and conversion from notification data to layout values.

RxKeyboard packages that work behind a singleton and three predefined Drivers. For an application already standardized on RxSwift, this can reduce repeated reactive plumbing and gives similar keyboard measurements a single API. It does not support non-iOS keyboard workflows, and the README documents only iOS. It also adds RxSwift and RxCocoa dependencies to a use case that UIKit can otherwise handle without them.

This is a real architectural trade-off rather than a simple feature comparison. Choose manual UIKit notifications when avoiding reactive dependencies is more important than shared Drivers. Choose RxKeyboard when its signals match the layout state already consumed by a reactive view controller. Neither approach automatically identifies the active field or guarantees that every keyboard event maps to the desired scrolling behavior.

Release, Maintenance, and Dependency Constraints

The repository is not archived, and its last push was on 2026-06-23. That is the most concrete maintenance fact available from the repository listing. The latest listed release is RxKeyboard 2.0.1 from 2023-04-12, followed by 2.0.0 from 2021-01-16 and 1.0.0 from 2019-05-27. Recent repository activity and release age should be considered separately because a new push does not by itself establish that a new release has been published.

RxKeyboard is distributed under the MIT license. That identifier permits reuse and modification under the license's terms, but this review does not interpret the legal text or provide legal advice. Applications still need to review the repository's `LICENSE` file and account for the separate terms of RxSwift and RxCocoa.

Compatibility is another adoption constraint. The README states Swift 5.1, iOS 9 or later, RxSwift 6.0 or later, and RxCocoa 6.0 or later. The Swift 5.0 badge shown near the project name differs from the stated Swift 5.1 requirement, so package resolution and compiler compatibility should be checked in the consuming project rather than inferred from the badge. The Carthage section is more restrictive in practice because it lists only binary releases from older Xcode and Swift combinations. For current dependency planning, the documented CocoaPods path has the clearest support.

Editorial conclusion

RxKeyboard suits iOS developers already using RxSwift who want keyboard state delivered through Drivers for scroll view insets, offsets, and toolbar movement. It is a poor fit for UIKit code without RxSwift or for projects needing undocumented cross-platform support. Before adoption, verify that CocoaPods can resolve RxKeyboard with RxSwift 6 and confirm your layout strategy against the linked example project.

Frequently asked questions

How do I install RxKeyboard in an iOS project?

The README documents adding `pod 'RxKeyboard'` to the `Podfile`. It also lists Carthage, although the available Carthage entries are older binary builds tied to specified Xcode and Swift versions.

Which RxKeyboard signal should I use to adjust a UIScrollView?

The README uses `visibleHeight` to update `contentInset.bottom` and `willShowVisibleHeight` when adjusting `contentOffset.y`. The choice depends on whether the screen needs ongoing visible height or an adjustment as the keyboard is about to show.

Does RxKeyboard require RxSwift and RxCocoa?

Yes. The documented dependencies are RxSwift 6.0 or later and RxCocoa 6.0 or later, and the project requirements list Swift 5.1 with iOS 9 or later.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. RxSwiftCommunity/RxKeyboard on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rxswiftcommunity-rxkeyboard.svg)](https://hysenlabs.com/projects/rxswiftcommunity-rxkeyboard)

Was this useful?