Name: RxGesture
Owner: RxSwift Community
Description: RxSwift reactive wrapper for view gestures
Created: 2016-03-22 09:54:11.0
Updated: 2018-05-24 07:44:10.0
Pushed: 2018-05-10 13:04:38.0
Size: 2181
Language: Swift
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
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:
.rx
apGesture()
hen(.recognized)
ubscribe(onNext: { _ in
//react to taps
isposed(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:
.rx
nyGesture(.tap(), .swipe([.up, .down]))
hen(.recognized)
ubscribe(onNext: { _ in
//dismiss presented photo
isposed(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:)
)
.rx.tapGesture() -> ControlEvent<UITapGestureRecognizer>
.rx.pinchGesture() -> ControlEvent<UIPinchGestureRecognizer>
.rx.swipeGesture(.left) -> ControlEvent<UISwipeGestureRecognizer>
.rx.panGesture() -> ControlEvent<UIPanGestureRecognizer>
.rx.longPressGesture() -> ControlEvent<UILongPressGestureRecognizer>
.rx.rotationGesture() -> ControlEvent<UIRotationGestureRecognizer>
.rx.screenEdgePanGesture() -> ControlEvent<UIScreenEdgePanGestureRecognizer>
.rx.anyGesture(.tap(), ...) -> ControlEvent<UIGestureRecognizer>
.rx.anyGesture(.pinch(), ...) -> ControlEvent<UIGestureRecognizer>
.rx.anyGesture(.swipe(.left), ...) -> ControlEvent<UIGestureRecognizer>
.rx.anyGesture(.pan(), ...) -> ControlEvent<UIGestureRecognizer>
.rx.anyGesture(.longPress(), ...) -> ControlEvent<UIGestureRecognizer>
.rx.anyGesture(.rotation(), ...) -> ControlEvent<UIGestureRecognizer>
.rx.anyGesture(.screenEdgePan(), ...) -> ControlEvent<UIGestureRecognizer>
.rx.clickGesture() -> ControlEvent<NSClickGestureRecognizer>
.rx.rightClickGesture() -> ControlEvent<NSClickGestureRecognizer>
.rx.panGesture() -> ControlEvent<NSPanGestureRecognizer>
.rx.pressGesture() -> ControlEvent<NSPressGestureRecognizer>
.rx.rotationGesture() -> ControlEvent<NSRotationGestureRecognizer>
.rx.magnificationGesture() -> ControlEvent<NSMagnificationGestureRecognizer>
.rx.anyGesture(.click(), ...) -> ControlEvent<NSGestureRecognizer>
.rx.anyGesture(.rightClick(), ...) -> ControlEvent<NSGestureRecognizer>
.rx.anyGesture(.pan(), ...) -> ControlEvent<NSGestureRecognizer>
.rx.anyGesture(.press(), ...) -> ControlEvent<NSGestureRecognizer>
.rx.anyGesture(.rotation(), ...) -> ControlEvent<NSGestureRecognizer>
.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()
.
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:
.rx.tapGesture().when(.recognized)
.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:
.rx
nyGesture(.tap(), .swipe([.up, .down]))
hen(.recognized)
ubscribe(onNext: { gesture in
// Called whenever a tap, a swipe-up or a swipe-down is recognized (state == .recognized)
isposed(by: bag)
.rx
nyGesture(
(.tap(), when: .recognized),
(.pan(), when: .ended)
ubscribe(onNext: { gesture in
// Called whenever:
// - a tap is recognized (state == .recognized)
// - or a pan is ended (state == .ended)
isposed(by: bag)
The demo app includes examples for all recognizers ?? iOS, macOS.
Each gesture recognizer has a default RxGestureRecognizerDelegate
. It allows you to customize every delegate method using a policy:
.always
will return true
to the corresponding delegate method.never
will return false
to the corresponding delegate method.custom
takes an associated closure that will be executed to return a value to the corresponding delegate methodHere are the available policies with their corresponding delegate method:
nPolicy -> gestureRecognizerShouldBegin(:_)
hReceptionPolicy -> gestureRecognizer(_:shouldReceive:)
FailureRequirementPolicy -> gestureRecognizer(_:shouldBeRequiredToFailBy:)
rFailureRequirementPolicy -> gestureRecognizer(_:shouldRequireFailureOf:)
ltaneousRecognitionPolicy -> gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
tRecognitionAttemptPolicy -> gestureRecognizer(_:shouldAttemptToRecognizeWith:) // macOS only
sReceptionPolicy -> gestureRecognizer(_:shouldReceive:) // iOS only
This delegate can be customized in the configuration closure:
.rx.tapGesture(configuration: { gestureRecognizer, delegate in
legate.simultaneousRecognitionPolicy = .always // (default value)
or
legate.simultaneousRecognitionPolicy = .never
or
legate.simultaneousRecognitionPolicy = .custom { gestureRecognizer, otherGestureRecognizer in
return otherGestureRecognizer is UIPanGestureRecognizer
legate.otherFailureRequirementPolicy = .custom { gestureRecognizer, otherGestureRecognizer in
return otherGestureRecognizer is UILongPressGestureRecognizer
Default values can be found in RxGestureRecognizerDelegate.swift
.
You can also replace the default delegate by your own, or remove it.
.rx.tapGesture { [unowned self] gestureRecognizer, delegate in
stureRecognizer.delegate = nil
or
stureRecognizer.delegate = self
This library depends on both RxSwift and RxCocoa.
Add this to Podfile
"RxGesture"
ash
d install
Add this to Cartfile
ub "RxSwiftCommunity/RxGesture" ~> 1.1.1
ash
rthage update
Everyone in the RxSwift Slack channel ?
RxGesture is available under the MIT license. See the LICENSE file for more info.