RxSwiftCommunity/RxGesture
RxSwiftCommunity/RxGesture has 1,377 GitHub stars and 180 forks. GitHot measured 0 stars in 24 hours and 0 in 7 days. Last checked 2026-11-09 05:28 UTC. Last push 2026-04-08.
RxSwift reactive wrapper for view gestures
Measured star growth
- in 24h
- 0
- in 7 days
- 0
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalRxGesture
Usage

To run the example project, clone the repo, in the Example folder open RxGesture.xcworkspace.
You might need to run pod install from the Example directory first.
RxGesture allows you to easily turn any view into a tappable or swipeable control like so:
view.rx
.tapGesture()
.when(.recognized)
.subscribe(onNext: { _ in
//react to taps
})
.disposed(by: stepBag)
You can also react to more than one gesture. For example to dismiss a photo preview you might want to do that when the user taps it, or swipes up or down:
view.rx
.anyGesture(.tap(), .swipe([.up, .down]))
.when(.recognized)
.subscribe(onNext: { _ in
//dismiss presented photo
})
.disposed(by: stepBag)
rx.gesture is defined as Observable<G> where G is the actual type of the gesture recognizer so what it emits is the gesture recognizer itself (handy if want to call methods like asLocation(in view:) or asTranslation(in view:))
On iOS, RxGesture supports:
view.rx.tapGesture() -> ControlEvent<UITapGestureRecognizer>
view.rx.pinchGesture() -> ControlEvent<UIPinchGestureRecognizer>
view.rx.swipeGesture(.left) -> ControlEvent<UISwipeGestureRecognizer>
view.rx.panGesture() -> ControlEvent<UIPanGestureRecognizer>
view.rx.longPressGesture() -> ControlEvent<UILongPressGestureRecognizer>
view.rx.rotationGesture() -> ControlEvent<UIRotationGestureRecognizer>
view.rx.screenEdgePanGesture() -> ControlEvent<UIScreenEdgePanGestureRecognizer>
view.rx.hoverGesture() -> ControlEvent<UIHoverGestureRecognizer>
view.rx.anyGesture(.tap(), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.pinch(), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.swipe(.left), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.pan(), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.longPress(), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.rotation(), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.screenEdgePan(), ...) -> ControlEvent<UIGestureRecognizer>
view.rx.anyGesture(.hover(), ...) -> ControlEvent<UIGestureRecognizer>
On macOS, RxGesture supports:
view.rx.clickGesture() -> ControlEvent<NSClickGestureRecognizer>
view.rx.rightClickGesture() -> ControlEvent<NSClickGestureRecognizer>
view.rx.panGesture() -> ControlEvent<NSPanGestureRecognizer>
view.rx.pressGesture() -> ControlEvent<NSPressGestureRecognizer>
view.rx.rotationGesture() -> ControlEvent<NSRotationGestureRecognizer>
view.rx.magnificationGesture() -> ControlEvent<NSMagnificationGestureRecognizer>
view.rx.anyGesture(.click(), ...) -> ControlEvent<NSGestureRecognizer>
view.rx.anyGesture(.rightClick(), ...) -> ControlEvent<NSGestureRecognizer>
view.rx.anyGesture(.pan(), ...) -> ControlEvent<NSGestureRecognizer>
view.rx.anyGesture(.press(), ...) -> ControlEvent<NSGestureRecognizer>
view.rx.anyGesture(.rotation(), ...) -> ControlEvent<NSGestureRecognizer>
view.rx.anyGesture(.magnification(), ...) -> ControlEvent<NSGestureRecognizer>
ℹ️ If you use a gesture recognizer alone, prefer the view.rx.fooGesture() syntax over view.rx.anyGesture(.foo()) because it returns the concrete UIGestureRecognizer subclass and avoid you to cast it in subscribe().
Filtering State
By default, there is no filter on the state of the gesture recognizer. That means that you will always receive a first event with the initial state of the gesture recognizer (almost always .possible).
Here are the preferred states that can be used for each kind of gestures (iOS and macOS):
| Kind | States |
|---|---|
.tap() .click() .rightClick() .swipe() |
.recognized |
.longPress() .press() |
.began |
.pan() .pinch() .rotation() .magnification() .screenEdgePan() |
.began .changed .ended |
You usually filter the state using the .when() operator:
view.rx.tapGesture().when(.recognized)
view.rx.panGesture().when(.began, .changed, .ended)
If you are observing multiple gestures at once, you can use the .when() operator if you want to filter against the same state for all gesture recognizers, or use the tuple syntax for individual filtering:
view.rx
.anyGesture(.tap(), .swipe([.up, .down]))
.when(.recognized)
.subscribe(onNext: { gesture in
// Called whenever a tap, a swipe-up or a swipe-down is recognized (state == .recognized)
})
.disposed(by: bag)
view.rx
.anyGesture(
(.tap(), when: .recognized),
(.pan(), when: .ended)
)
.subscribe(onNext: { gesture in
// Called whenever:
// - a tap is recognized (state == .recognized)
// - or a pan is ended (state == .ended)
})
.disposed(by: bag)
The demo app includes examples for all recognizers ➡️ iOS, macOS.
Delegate customization
Lightweight customization
Each gesture recognizer has a default RxGestureRecognizerDelegate. It allows you to customize every delegate method using a policy:
.alwayswill returntrueto the corresponding delegate method.neverwill returnfalseto the corresponding delegate method.customtakes an associated closure that will be executed to return a value to the corresponding delegate method
Here are the available policies with their corresponding delegate method:
beginPolicy -> gestureRecognizerShouldBegin(:_)
touchReceptionPolicy -> gestureRecognizer(_:shouldReceive:)
selfFailureRequirementPolicy -> gestureRecognizer(_:shouldBeRequiredToFailBy:)
otherFailureRequirementPolicy -> gestureRecognizer(_:shouldRequireFailureOf:)
simultaneousRecognitionPolicy -> gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
eventRecognitionAttemptPolicy -> gestureRecognizer(_:shouldAttemptToRecognizeWith:) // macOS only
pressReceptionPolicy -> gestureRecognizer(_:shouldReceive:) // iOS only
This delegate can be customized in the configuration closure:
view.rx.tapGesture(configuration: { gestureRecognizer, delegate in
delegate.simultaneousRecognitionPolicy = .always // (default value)
// or
delegate.simultaneousRecognitionPolicy = .never
// or
delegate.simultaneousRecognitionPolicy = .custom { gestureRecognizer, otherGestureRecognizer in
return otherGestureRecognizer is UIPanGestureRecognizer
}
delegate.otherFailureRequirementPolicy = .custom { gestureRecognizer, otherGestureRecognizer in
return otherGestureRecognizer is UILongPressGestureRecognizer
}
})
Default values can be found in RxGestureRecognizerDelegate.swift.
Full customization
You can also replace the default delegate by your own, or remove it.
view.rx.tapGesture { [unowned self] gestureRecognizer, delegate in
gestureRecognizer.delegate = nil
// or
gestureRecognizer.delegate = self
}
Requirements
This library depends on both RxSwift and RxCocoa.
Installation
CocoaPods
Add this to Podfile
pod "RxGesture"
$ pod install
Carthage
Add this to Cartfile
github "RxSwiftCommunity/RxGesture" ~> 3.0
$ carthage update
Thanks
Everyone in the RxSwift Slack channel 💯
License
RxGesture is available under the MIT license. See the LICENSE file for more info.
Explore related projects
freeCodeCamp/freeCodeCamp
freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.
458,782 starsdonnemartin/system-design-primer
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
377,374 starsreact/react
The library for web and native user interfaces.
252,429 starsvuejs/vue
This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
212,631 stars