Convert Figma logo to code with AI

RxSwiftCommunity logoRxKeyboard

Reactive Keyboard in iOS

1,600
175
1,600
26

Top Related Projects

24,320

Reactive Programming in Swift

Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

4,233

A Swift binding framework

15,085

Network abstraction layer written in Swift.

A library for reactive and unidirectional Swift applications

UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...)

Quick Overview

RxKeyboard is a reactive extension for keyboard events in iOS applications using RxSwift. It provides a convenient way to handle keyboard appearance and disappearance, as well as keyboard frame changes, in a reactive programming style.

Pros

  • Simplifies keyboard event handling with reactive programming
  • Provides easy access to keyboard frame and animation duration
  • Integrates seamlessly with RxSwift and RxCocoa
  • Supports both UIKit and SwiftUI

Cons

  • Requires knowledge of RxSwift and reactive programming concepts
  • May introduce additional complexity for simple keyboard handling scenarios
  • Dependency on RxSwift might increase app size
  • Limited documentation and examples available

Code Examples

  1. Observing keyboard frame changes:
import RxKeyboard
import RxSwift

RxKeyboard.instance.frame
    .drive(onNext: { frame in
        print("Keyboard frame: \(frame)")
    })
    .disposed(by: disposeBag)
  1. Adjusting view constraints based on keyboard visibility:
import RxKeyboard
import RxSwift
import RxCocoa

RxKeyboard.instance.visibleHeight
    .drive(onNext: { [weak self] keyboardVisibleHeight in
        self?.view.layoutIfNeeded()
        self?.bottomConstraint.constant = keyboardVisibleHeight
        UIView.animate(withDuration: 0.3) {
            self?.view.layoutIfNeeded()
        }
    })
    .disposed(by: disposeBag)
  1. Dismissing keyboard on tap gesture:
import RxKeyboard
import RxSwift
import RxCocoa
import UIKit

let tapGesture = UITapGestureRecognizer()
view.addGestureRecognizer(tapGesture)

tapGesture.rx.event
    .subscribe(onNext: { _ in
        self.view.endEditing(true)
    })
    .disposed(by: disposeBag)

Getting Started

  1. Install RxKeyboard using CocoaPods by adding the following to your Podfile:
pod 'RxKeyboard'
  1. Import RxKeyboard in your Swift file:
import RxKeyboard
  1. Start observing keyboard events:
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        RxKeyboard.instance.visibleHeight
            .drive(onNext: { [weak self] keyboardVisibleHeight in
                // Handle keyboard height changes
            })
            .disposed(by: disposeBag)
    }
}

Competitor Comparisons

24,320

Reactive Programming in Swift

Pros of RxSwift

  • Comprehensive reactive programming framework for Swift
  • Large community and extensive documentation
  • Supports a wide range of reactive programming patterns and operators

Cons of RxSwift

  • Steeper learning curve for developers new to reactive programming
  • Can lead to complex code if not used carefully
  • Larger library size compared to more focused solutions

Code Comparison

RxSwift (general reactive programming):

Observable.from([1, 2, 3, 4, 5])
    .filter { $0 % 2 == 0 }
    .map { $0 * 2 }
    .subscribe(onNext: { print($0) })

RxKeyboard (keyboard-specific reactive programming):

RxKeyboard.instance.visibleHeight
    .drive(onNext: { height in
        print("Keyboard height: \(height)")
    })
    .disposed(by: disposeBag)

Summary

RxSwift is a comprehensive reactive programming framework for Swift, offering a wide range of features and patterns. It has a large community and extensive documentation but comes with a steeper learning curve and potential for complex code. RxKeyboard, on the other hand, is a focused library specifically for handling keyboard events reactively. It builds on top of RxSwift, providing a simpler API for keyboard-related tasks. While RxSwift is more versatile, RxKeyboard offers a streamlined solution for keyboard management in iOS applications.

Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

Pros of ReactiveCocoa

  • More comprehensive framework for reactive programming in Swift and Objective-C
  • Supports a wider range of reactive patterns and operators
  • Larger community and ecosystem with more resources and extensions

Cons of ReactiveCocoa

  • Steeper learning curve due to its broader scope
  • Potentially more complex setup and integration for simple use cases
  • Heavier framework with more overhead compared to RxKeyboard

Code Comparison

ReactiveCocoa:

let (signal, observer) = Signal<String, Never>.pipe()
signal.observeValues { value in
    print("Received value: \(value)")
}
observer.send(value: "Hello, ReactiveCocoa!")

RxKeyboard:

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

ReactiveCocoa provides a more general-purpose reactive programming framework, while RxKeyboard focuses specifically on handling keyboard events in iOS applications. ReactiveCocoa offers greater flexibility and a wider range of reactive programming capabilities, but it may be overkill for projects that only need keyboard handling. RxKeyboard, on the other hand, provides a simpler and more targeted solution for keyboard-related reactive programming, making it easier to integrate for specific use cases.

4,233

A Swift binding framework

Pros of Bond

  • More comprehensive reactive programming framework, offering a wider range of features beyond keyboard handling
  • Supports data binding and UI synchronization, making it suitable for larger, more complex applications
  • Provides a declarative approach to UI development, potentially simplifying code structure

Cons of Bond

  • Steeper learning curve due to its broader scope and more extensive API
  • May introduce unnecessary complexity for projects that only require keyboard handling
  • Larger library size, which could impact app size and compilation time

Code Comparison

RxKeyboard:

RxKeyboard.instance.visibleHeight
    .drive(onNext: { [weak self] keyboardVisibleHeight in
        self?.tableViewBottomConstraint.constant = keyboardVisibleHeight
    })
    .disposed(by: disposeBag)

Bond:

let keyboardHeight = Observable<CGFloat>()
keyboardHeight
    .bind(to: tableViewBottomConstraint.constant)
    .dispose(in: bag)

While both libraries use reactive programming concepts, Bond's approach is more generalized and can be applied to various UI elements beyond just keyboard handling. RxKeyboard provides a more specialized solution focused specifically on keyboard interactions.

15,085

Network abstraction layer written in Swift.

Pros of Moya

  • More comprehensive networking abstraction layer
  • Supports multiple request types and response handling
  • Extensive documentation and community support

Cons of Moya

  • Steeper learning curve due to its broader scope
  • May be overkill for simple API interactions
  • Requires more setup and configuration

Code Comparison

RxKeyboard:

RxKeyboard.instance.frame
    .drive(onNext: { frame in
        // Handle keyboard frame changes
    })
    .disposed(by: disposeBag)

Moya:

provider = MoyaProvider<MyAPI>()
provider.rx.request(.userProfile)
    .map(User.self)
    .subscribe(onSuccess: { user in
        // Handle user data
    })
    .disposed(by: disposeBag)

Summary

While RxKeyboard focuses specifically on keyboard management in iOS applications, Moya is a more comprehensive networking library. RxKeyboard provides a simpler, more targeted solution for keyboard-related tasks, while Moya offers a robust framework for handling various API interactions. The choice between the two depends on the specific needs of your project. If you only need keyboard management, RxKeyboard might be more suitable. However, if you're looking for a full-featured networking solution, Moya would be the better choice despite its steeper learning curve.

A library for reactive and unidirectional Swift applications

Pros of ReactorKit

  • Provides a comprehensive architecture for building reactive apps
  • Offers a clear separation of concerns with its unidirectional data flow
  • Supports easy testing with a view-independent business logic layer

Cons of ReactorKit

  • Steeper learning curve due to its more complex architecture
  • May be overkill for simpler applications
  • Requires more boilerplate code compared to RxKeyboard

Code Comparison

ReactorKit:

struct Reactor: ReactorKit.Reactor {
    enum Action { case increment, decrement }
    enum Mutation { case increaseValue, decreaseValue }
    struct State { var value: Int = 0 }

    func mutate(action: Action) -> Observable<Mutation>
    func reduce(state: State, mutation: Mutation) -> State
}

RxKeyboard:

RxKeyboard.instance.visibleHeight
    .drive(onNext: { keyboardVisibleHeight in
        // Handle keyboard height changes
    })
    .disposed(by: disposeBag)

ReactorKit is a full-fledged architecture for building reactive applications, while RxKeyboard focuses specifically on handling keyboard events in a reactive manner. ReactorKit offers more structure and scalability for complex apps, but comes with a steeper learning curve. RxKeyboard provides a simpler, more focused solution for keyboard management in RxSwift projects.

UITableView and UICollectionView Data Sources for RxSwift (sections, animated updates, editing ...)

Pros of RxDataSources

  • More versatile, handling complex data structures for UITableView and UICollectionView
  • Provides automatic diffing and animating of data changes
  • Offers a more declarative approach to managing data sources

Cons of RxDataSources

  • Steeper learning curve due to its more complex API
  • May be overkill for simple table or collection views
  • Requires more setup code compared to RxKeyboard's straightforward implementation

Code Comparison

RxDataSources:

let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Int>>(
    configureCell: { (_, tv, indexPath, element) in
        let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
        cell.textLabel?.text = "\(element)"
        return cell
    }
)

RxKeyboard:

RxKeyboard.instance.visibleHeight
    .drive(onNext: { [weak self] keyboardVisibleHeight in
        self?.view.frame.origin.y = -keyboardVisibleHeight
    })
    .disposed(by: disposeBag)

RxDataSources focuses on managing complex data structures for table and collection views, while RxKeyboard specifically handles keyboard-related events and animations. RxDataSources is more powerful but complex, whereas RxKeyboard is simpler and more focused on its specific use case.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

RxKeyboard

Swift CocoaPods Build Status Carthage compatible

RxKeyboard provides a reactive way of observing keyboard frame changes. Forget about keyboard notifications. It also perfectly works with UIScrollViewKeyboardDismissMode.interactive.

rxkeyboard-message rxkeyboard-textview

Getting Started

RxKeyboard provides two Drivers.

/// An observable keyboard frame.
let frame: Driver<CGRect>

/// An observable visible height of keyboard. Emits keyboard height if the keyboard is visible
/// or `0` if the keyboard is not visible.
let visibleHeight: Driver<CGFloat>

/// Same with `visibleHeight` but only emits values when keyboard is about to show. This is
/// useful when adjusting scroll view content offset.
let willShowVisibleHeight: Driver<CGFloat>

Use RxKeyboard.instance to get singleton instance.

RxKeyboard.instance

Subscribe RxKeyboard.instance.frame to observe keyboard frame changes.

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

Tips and Tricks

  • 🔗 I want to adjust UIScrollView's contentInset to fit keyboard height.

    RxKeyboard.instance.visibleHeight
      .drive(onNext: { [scrollView] keyboardVisibleHeight in
        scrollView.contentInset.bottom = keyboardVisibleHeight
      })
      .disposed(by: disposeBag)
    
  • 🔗 I want to adjust UIScrollView's contentOffset to fit keyboard height.

    RxKeyboard.instance.willShowVisibleHeight
      .drive(onNext: { [scrollView] keyboardVisibleHeight in
        scrollView.contentOffset.y += keyboardVisibleHeight
      })
      .disposed(by: disposeBag)
    
  • 🔗 I want to make UIToolbar move along with the keyboard in an interactive dismiss mode. (Just like the wonderful GIF above!)

    If you're not using Auto Layout:

    RxKeyboard.instance.visibleHeight
      .drive(onNext: { [toolbar, view] keyboardVisibleHeight in
        toolbar.frame.origin.y = view.frame.height - toolbar.frame.height - keyboardVisibleHeight
      })
      .disposed(by: disposeBag)
    

    If you're using Auto Layout, you have to capture the toolbar's bottom constraint and set constant to keyboard visible height.

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

    Note: In real world, you should use setNeedsLayout() and layoutIfNeeded() with animation block. See the example project for example.

  • Anything else? Please open an issue or make a Pull Request.

Dependencies

Requirements

  • Swift 5.1
  • iOS 9+

Contributing

In development, RxKeyboard manages dependencies with Swift Package Manager. Use the command below in order to generate a Xcode project file. Note that .xcodeproj file changes are not tracked via git.

$ swift package generate-xcodeproj

Installation

  • Using CocoaPods:

    pod 'RxKeyboard'
    
  • Using Carthage:

    binary "https://raw.githubusercontent.com/RxSwiftCommunity/RxKeyboard/master/RxKeyboard.json"
    

    ⚠️ With Carthage, RxKeyboard only supports binary installation:

    • 0.9.2
      • Xcode 10.1 (10B61)
      • Swift 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)
    • 0.9.0
      • Xcode 10 (10A255)
      • Swift 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1)
    • 0.8.2
      • Xcode 9.3 (9E145)
      • Swift 4.1.0 (swiftlang-902.0.48 clang-902.0.37.1)
    • 0.7.1
      • Xcode 9.1 (9B55)
      • Swift 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38)
    • 0.7.0
      • 9.0.1 (9A1004)
      • Swift 4.0 (swiftlang-900.0.65.2 clang-900.0.37)

License

RxKeyboard is under MIT license.