RxSwift reactive wrapper for view gestures

Overview

RxGesture

Version License Platform

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:

  • .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 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.

Comments
  • Swift 4 support

    Swift 4 support

    Just wondering if there are any plans for Swift 4/Xcode 9 support. The library currently doesn't compile under Swift 4, but I can fix it and create a pull request if someone with write access makes a swift-4 branch for me to compare against.

    opened by sidmani 19
  • Refactor

    Refactor

    RxGesture is a nice extension but suffers from many drawbacks :

    • It's not extendable : if you want to support a new UIGestureRecognizer subclass, you have to add an enum case and modify the gesture() method to support that case. It leads to an incredible method of 150+ lines.

    • PanConfig and RotateConfig are really weird. There are used to configure the gesture AND to emit gesture's values like velocity, translation, rotation, etc...

    • pan and rotation gestures are automatically reused and shareReplay(). This could lead to unexpected behaviors. IMHO, it should be the API consumer to decide wether or not they want to shareReplay() their gesture recognizer.

    • enum cases can't have default values. As a workaround, there was an extra case for some gestures (ex: .tap / .tapNumberOfTimes), but it's not really convenient nor extendable

    This PR tries to address all of these points.

    It's still work in progress :

    • [x] refactor support of iOS gesture recognizers
    • [x] refactor support of macOS gesture recognizers
    • [x] support all iOS native gesture recognizers
    • [x] support all macOS native gesture recognizers
    • [x] add method inline documentation
    • [x] update README.md

    Feel free to comment or suggest any modification to the proposed architecture 🤗

    enhancement help wanted 
    opened by jegnux 15
  • Carthage build fail in release 1.0.1

    Carthage build fail in release 1.0.1

    I'm getting the following error with your latest release(1.0.1) using Carthage. it was working before so I have to explicitly specify 1.0.0 in my Cartfile which is not my preferred way.

    Building scheme "RxGesture-iOS" in RxGesture.xcodeproj Build Failed Task failed with exit code 65: /usr/bin/xcrun xcodebuild -project PATH_AO_APP/Carthage/Checkouts/RxGesture/RxGesture/RxGesture.xcodeproj -scheme RxGesture-iOS -configuration Release -derivedDataPath ../Caches/org.carthage.CarthageKit/DerivedData/RxGesture/1.0.1 -sdk iphoneos ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES clean build

    I tried to build it and the error is PATH_TO_APP/Carthage/Checkouts/RxGesture/Pod/Classes/View+RxGesture.swift:102:22: error: value of type 'Observable' has no member 'bind' .startWith(gesture)

    FYI: I had a look into the file and compared with the previous version

                    let disposable = genericGesture.rx.event
                        .map { $0 as! G }
                        .startWith(gesture)
                        .bindNext(observer.onNext)
    

    has been changed to:

                    let disposable = genericGesture.rx.event
                        .map { $0 as! G }
                        .startWith(gesture)
                        .bind(onNext: observer.onNext)
    

    rollback works so if I change this line build succeeds

    opened by bidadh 13
  • Swift 4.2 release

    Swift 4.2 release

    Hey @jegnux - Seems like the master branch has Swift 4.2 properly fixed, but a release wasn't cut yet :)

    I could do it myself but preferred leaving it to you :]

    Let me know if I can help!

    opened by freak4pc 11
  • Target taps

    Target taps

    I added .targetTap and .targetLongPress events. This events supplement .tap and .longPress events, but also they hold location in view where the event was fired.

    So, .targetTap works as follows:

    hoursContainer.rx_gesture(.TargetTap(.Anywhere))
        .subscribeNext { gesture in
            switch gesture {
            case .TargetTap(let data):
                print(data.location) // prints location of the tap in hoursContainer view
                break
            default: break
            }
        }
        .addDisposableTo(bag)
    

    As for .targetLongPress, there are .Any, .Began, .Changed, .Ended states as they are in Pan or Rotate events.

    hoursContainer.rx_gesture(.TargetLongPress(.Began), .TargetLongPress(.Ended))
        .subscribeNext { (gesture) in
            switch gesture {
            case .TargetLongPress(let data):
                print(data.location) // prints coordinates of location where user started to hold his finger and finally released
                break
            default:
                break
            }
        }
        .addDisposableTo(bag)
    

    I think this will be useful when user creates a custom view with specific logic.

    opened by olferuk 10
  • ExclusiveGestureRecognizerDelegate

    ExclusiveGestureRecognizerDelegate

    I had an issue similar to #42 and needed an alternative to the default PermissiveGestureRecognizerDelegate. I though it would be useful to have this implementation in the pod for easy reuse.

    opened by Coledunsby 9
  • Xcode 11 and Carthage: exit code 65 (compile error: use of undeclared type 'Element')

    Xcode 11 and Carthage: exit code 65 (compile error: use of undeclared type 'Element')

    I'm trying to update everything to Xcode 11/Swift 5.1 and I'm finding this error on Carthage:

    *** Building scheme "RxBlocking" in Rx.xcworkspace
    *** Building scheme "RxRelay" in Rx.xcworkspace
    *** Building scheme "RxSwift" in Rx.xcworkspace
    *** Building scheme "RxCocoa" in Rx.xcworkspace
    *** Building scheme "RxTest" in Rx.xcworkspace
    *** Building scheme "RxDataSources" in RxDataSources.xcodeproj
    *** Building scheme "Differentiator" in RxDataSources.xcodeproj
    *** Building scheme "RxBlocking-iOS" in Rx.xcworkspace
    *** Building scheme "RxCocoa-iOS" in Rx.xcworkspace
    *** Building scheme "RxSwift-iOS" in Rx.xcworkspace
    *** Building scheme "RxTests-iOS" in Rx.xcworkspace
    *** Building scheme "RxGesture-iOS" in RxGesture.xcodeproj
    Build Failed
    	Task failed with exit code 65:
    

    These are the last lines of the compiling log:

    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIPanGestureRecognizer+RxGesture.swift:51:32: error: use of undeclared type 'Element'
    extension ObservableType where Element: UIPanGestureRecognizer {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIPanGestureRecognizer+RxGesture.swift:60:45: error: cannot convert value of type 'Self.E' to expected argument type 'GestureRecognizer' (aka 'UIGestureRecognizer')
                let view = view.targetView(for: gesture)
                                                ^~~~~~~
                                                        as! GestureRecognizer
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/TouchDownGestureRecognizer.swift:82:32: error: use of undeclared type 'Element'
    extension ObservableType where Element: TouchDownGestureRecognizer {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/TouchDownGestureRecognizer.swift:88:30: error: value of type 'Self.E' has no member 'touches'
            return self.map { $0.touches }
                              ~~ ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/ForceTouchGestureRecognizer.swift:85:32: error: use of undeclared type 'Element'
    extension ObservableType where Element: ForceTouchGestureRecognizer {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/ForceTouchGestureRecognizer.swift:91:30: error: value of type 'Self.E' has no member 'force'
            return self.map { $0.force }
                              ~~ ^~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/TransformGestureRecognizers.swift:58:32: error: use of undeclared type 'Element'
    extension ObservableType where Element == TransformGestureRecognizers {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/TransformGestureRecognizers.swift:60:73: error: use of undeclared type 'Element'
        public func when(_ states: GestureRecognizerState...) -> Observable<Element> {
                                                                            ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/GestureRecognizer+RxGesture.swift:24:32: error: use of undeclared type 'Element'
    extension ObservableType where Element: GestureRecognizer {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/GestureRecognizer+RxGesture.swift:32:73: error: use of undeclared type 'Element'
        public func when(_ states: GestureRecognizerState...) -> Observable<Element> {
                                                                            ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/GestureRecognizer+RxGesture.swift:44:74: error: use of undeclared type 'Element'
        internal func when(_ states: [GestureRecognizerState]) -> Observable<Element> {
                                                                             ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/View+RxGesture.swift:36:43: error: closure tuple parameter '(AnyFactory, when: GestureRecognizerState)' (aka '(Factory<UIGestureRecognizer>, when: UIGestureRecognizer.State)') does not support destructuring
            let observables = factories.map { gesture, state in
                                              ^~~~~~~~~~~~~~
                                              (arg) -> <#Result#>
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/TransformGestureRecognizers.swift:70:65: error: value of type 'Self.E' has no member 'panGesture'
                let translationView = view.targetView(for: gestures.panGesture)
                                                           ~~~~~~~~ ^~~~~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/GestureRecognizer+RxGesture.swift:57:28: error: value of type 'Self.E' has no member 'location'
                return gesture.location(in: view.targetView(for: gesture))
                       ~~~~~~~ ^~~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIPinchGestureRecognizer+RxGesture.swift:51:32: error: use of undeclared type 'Element'
    extension ObservableType where Element: UIPinchGestureRecognizer {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIPinchGestureRecognizer+RxGesture.swift:58:29: error: value of type 'Self.E' has no member 'scale'
                return (gesture.scale, gesture.velocity)
                        ~~~~~~~ ^~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIPinchGestureRecognizer+RxGesture.swift:58:44: error: value of type 'Self.E' has no member 'velocity'
                return (gesture.scale, gesture.velocity)
                                       ~~~~~~~ ^~~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIRotationGestureRecognizer+RxGesture.swift:51:32: error: use of undeclared type 'Element'
    extension ObservableType where Element: UIRotationGestureRecognizer {
                                   ^~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIRotationGestureRecognizer+RxGesture.swift:58:29: error: value of type 'Self.E' has no member 'rotation'
                return (gesture.rotation, gesture.velocity)
                        ~~~~~~~ ^~~~~~~~
    /Users/fieldmargin/Xcode/notes-ios/Carthage/Checkouts/RxGesture/Pod/Classes/iOS/UIRotationGestureRecognizer+RxGesture.swift:58:47: error: value of type 'Self.E' has no member 'velocity'
                return (gesture.rotation, gesture.velocity)
                                          ~~~~~~~ ^~~~~~~~
    

    I'm using "master" and the resolved file points to the last commit https://github.com/RxSwiftCommunity/RxGesture/commit/bd13354b45507bb30e4f6ac7142b03cd60a0b244

    Swift on the console: Welcome to Apple Swift version 5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7).

    xcodebuild -version

    Xcode 11.0
    Build version 11A420a
    

    Cartfile.resolved:

    github "ReactiveX/RxSwift" "5.0.1"
    github "RxSwiftCommunity/RxDataSources" "4.0.1"
    github "RxSwiftCommunity/RxGesture" "bd13354b45507bb30e4f6ac7142b03cd60a0b244"
    github "RxSwiftCommunity/RxOptional" "4.0.0"
    github "RxSwiftCommunity/RxRealm" "bac74bdc0c04f5ef1c68d46021a115b536903366"
    github "RxSwiftCommunity/RxSwiftExt" "5.1.1"
    

    Any ideas on how to solve this would be appreciated!! Thanks!

    opened by lluisgerard 8
  • RxSwift & RxCocoa 5 compatibility?

    RxSwift & RxCocoa 5 compatibility?

    Hi. Now I cannot use RxGesture with recently released RxSwift & RxCocoa 5. (https://github.com/ReactiveX/RxSwift/releases) It requires RxCocoa 4.5.

    Any updates on compatibility plans? Thank you.

    Screenshot at Apr 30 14-51-04

    opened by Ariandr 8
  • Strange bug with `when` func

    Strange bug with `when` func

    I was getting this error, compiling with Xcode 9.0 and RxGesture 1.1.1:

    
    *** DESERIALIZATION FAILURE (please include this section in any bug report) ***
    result not found
    Cross-reference to module 'RxSwift'
    ... ObservableType
    ... E
    
    0  swift                    0x0000000109775dba PrintStackTraceSignalHandler(void*) + 42
    1  swift                    0x00000001097751f6 SignalHandler(int) + 662
    2  libsystem_platform.dylib 0x00007fffbea3db3a _sigtramp + 26
    3  libsystem_platform.dylib 0x000000010d1a0551 _sigtramp + 1316366897
    4  libsystem_c.dylib        0x00007fffbe8c2420 abort + 129
    5  swift                    0x0000000106e71c51 swift::ModuleFile::fatal(llvm::Error) + 1569
    6  swift                    0x0000000106e72102 swift::ModuleFile::getDecl(llvm::PointerEmbeddedInt<unsigned int, 31>, llvm::Optional<swift::DeclContext*>) + 130
    7  swift                    0x0000000106e7f08c swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 1836
    8  swift                    0x0000000106e7f4bc swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 2908
    9  swift                    0x0000000106e7fabb swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 4443
    10 swift                    0x0000000106e7f7c2 swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 3682
    11 swift                    0x0000000106e7bfda swift::ModuleFile::getDeclChecked(llvm::PointerEmbeddedInt<unsigned int, 31>, llvm::Optional<swift::DeclContext*>) + 40650
    12 swift                    0x0000000106e8aca1 swift::ModuleFile::loadAllMembers(swift::Decl*, unsigned long long) + 657
    13 swift                    0x00000001072e4536 swift::IterableDeclContext::loadAllMembers() const + 134
    14 swift                    0x000000010733e57c swift::NominalTypeDecl::lookupDirect(swift::DeclName, bool) + 364
    15 swift                    0x0000000106e84678 swift::ModuleFile::resolveCrossReference(swift::ModuleDecl*, unsigned int) + 3880
    16 swift                    0x0000000106e75b05 swift::ModuleFile::getDeclChecked(llvm::PointerEmbeddedInt<unsigned int, 31>, llvm::Optional<swift::DeclContext*>) + 14837
    17 swift                    0x0000000106e720d4 swift::ModuleFile::getDecl(llvm::PointerEmbeddedInt<unsigned int, 31>, llvm::Optional<swift::DeclContext*>) + 84
    18 swift                    0x0000000106e7f08c swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 1836
    19 swift                    0x0000000106e7f4bc swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 2908
    20 swift                    0x0000000106e7fabb swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 4443
    21 swift                    0x0000000106e7f7c2 swift::ModuleFile::getTypeChecked(llvm::PointerEmbeddedInt<unsigned int, 31>) + 3682
    22 swift                    0x0000000106e7bfda swift::ModuleFile::getDeclChecked(llvm::PointerEmbeddedInt<unsigned int, 31>, llvm::Optional<swift::DeclContext*>) + 40650
    23 swift                    0x0000000106e8aca1 swift::ModuleFile::loadAllMembers(swift::Decl*, unsigned long long) + 657
    24 swift                    0x00000001072e4536 swift::IterableDeclContext::loadAllMembers() const + 134
    25 swift                    0x000000010733e57c swift::NominalTypeDecl::lookupDirect(swift::DeclName, bool) + 364
    26 swift                    0x000000010733cf2e swift::DeclContext::lookupQualified(swift::Type, swift::DeclName, swift::NLOptions, swift::LazyResolver*, llvm::SmallVectorImpl<swift::ValueDecl*>&) const + 3518
    27 swift                    0x00000001071d1372 swift::TypeChecker::lookupMember(swift::DeclContext*, swift::Type, swift::DeclName, swift::OptionSet<swift::NameLookupFlags, unsigned int>)::$_1::operator()() const + 226
    28 swift                    0x00000001071d1239 swift::TypeChecker::lookupMember(swift::DeclContext*, swift::Type, swift::DeclName, swift::OptionSet<swift::NameLookupFlags, unsigned int>) + 281
    29 swift                    0x000000010711e239 swift::constraints::ConstraintSystem::lookupMember(swift::Type, swift::DeclName) + 473
    30 swift                    0x00000001070eae24 swift::constraints::ConstraintSystem::performMemberLookup(swift::constraints::ConstraintKind, swift::DeclName, swift::Type, swift::FunctionRefKind, swift::constraints::ConstraintLocator*, bool) + 2772
    31 swift                    0x00000001070ed1f9 swift::constraints::ConstraintSystem::simplifyMemberConstraint(swift::constraints::ConstraintKind, swift::Type, swift::DeclName, swift::Type, swift::DeclContext*, swift::FunctionRefKind, swift::OptionSet<swift::constraints::ConstraintSystem::TypeMatchFlags, unsigned int>, swift::constraints::ConstraintLocatorBuilder) + 345
    32 swift                    0x00000001070eeb8c swift::constraints::ConstraintSystem::simplifyConstraint(swift::constraints::Constraint const&) + 1164
    33 swift                    0x00000001070f1429 swift::constraints::ConstraintSystem::simplify(bool) + 105
    34 swift                    0x00000001070f2525 swift::constraints::ConstraintSystem::solveRec(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) + 53
    35 swift                    0x00000001070facd4 swift::constraints::ConstraintSystem::solveSimplified(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) + 22132
    36 swift                    0x00000001070f272e swift::constraints::ConstraintSystem::solveRec(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) + 574
    37 swift                    0x00000001070f2122 swift::constraints::ConstraintSystem::solve(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) + 354
    38 swift                    0x000000010718b127 swift::TypeChecker::solveForExpression(swift::Expr*&, swift::DeclContext*, swift::Type, swift::FreeTypeVariableBinding, swift::ExprTypeCheckListener*, swift::constraints::ConstraintSystem&, llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 8247
    39 swift                    0x000000010718b60d swift::TypeChecker::typeCheckExpression(swift::Expr*&, swift::DeclContext*, swift::TypeLoc, swift::ContextualTypePurpose, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>, swift::ExprTypeCheckListener*, swift::constraints::ConstraintSystem*) + 733
    40 swift                    0x000000010718e80e swift::TypeChecker::typeCheckBinding(swift::Pattern*&, swift::Expr*&, swift::DeclContext*, bool) + 366
    41 swift                    0x000000010718edcc swift::TypeChecker::typeCheckPatternBinding(swift::PatternBindingDecl*, unsigned int, bool) + 188
    42 swift                    0x00000001071a1bc5 (anonymous namespace)::DeclChecker::visit(swift::Decl*) + 1349
    43 swift                    0x0000000107210e9d swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 13805
    44 swift                    0x000000010720cd62 swift::TypeChecker::typeCheckAbstractFunctionBodyUntil(swift::AbstractFunctionDecl*, swift::SourceLoc) + 1090
    45 swift                    0x000000010721271b swift::TypeChecker::typeCheckAbstractFunctionBody(swift::AbstractFunctionDecl*) + 475
    46 swift                    0x000000010723031a swift::performTypeChecking(swift::SourceFile&, swift::TopLevelContext&, swift::OptionSet<swift::TypeCheckingFlags, unsigned int>, unsigned int, unsigned int, unsigned int, unsigned int) + 2506
    47 swift                    0x0000000106d60cc7 swift::CompilerInstance::performSema() + 5031
    48 swift                    0x00000001060e5552 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 1378
    49 swift                    0x00000001060e3784 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7716
    50 swift                    0x00000001060986a8 main + 12248
    51 libdyld.dylib            0x00007fffbe82e235 start + 1
    52 libdyld.dylib            0x0000000000000174 start + 1098719040
    Stack dump:
    0.	Program arguments: ...
    ...
    <lots of stuff>
    ...
    
    1.	While type-checking 'setupRx()' at /Users/home/Developer/Lottery.com/MUSL/PB&MM/Views/Components/Balls/MUSLMutableTicketBallView.swift:82:13
    2.	While type-checking declaration 0x7fdf4212df30 at /Users/home/Developer/Lottery.com/MUSL/PB&MM/Views/Components/Balls/MUSLMutableTicketBallView.swift:86:9
    3.	While type-checking expression at [/Users/home/Developer/Lottery.com/MUSL/PB&MM/Views/Components/Balls/MUSLMutableTicketBallView.swift:86:44 - line:90:13] RangeText="rx.model
                .asObservable()
                .flatMap { (model: MUSLMutableNumberBall) -> Observable<Int> in
                    model.rx.number.asObservable()
                }"
    4.	While loading members for extension of ObservableType in module 'RxGesture'
    5.	While deserializing 'when' (FuncDecl #201) in 'RxGesture'
    6.	While deserializing decl #667 (XREF) in 'RxGesture'
    7.	Cross-reference to module 'RxSwift'
    	... ObservableType
    	... E
    8.	While loading members for extension of ObservableType in module 'RxGesture'
    9.	While deserializing 'when' (FuncDecl #204) in 'RxGesture'
    

    I tried changing my code to be more type-explicit; same error. Then I tried removing the RxGesture library completely and it worked. Then I changed the public when function so it does not reference the internal when function (possible recursion-related compiler bug?):

        public func when(_ states: UIGestureRecognizerState...) -> Observable<E> {
            return filter { gesture in
                return states.contains(gesture.state)
            }
        }
    

    ...and it works.

    opened by JamesPerlman 8
  • If I subscribe the tapGesture at a custom view, how can i release the resource  in time in case it prevent the dealloc of the custom view.

    If I subscribe the tapGesture at a custom view, how can i release the resource in time in case it prevent the dealloc of the custom view.

    such as:

    class CustomView: UIView {
        init() {
            super.init(frame: CGRect())
    
            self.creatObservable()
        }
    
        func creatObservable() {        
            self.rx.tapGesture()
                .takeUntil(rx.deallocated)
                .subscribe({
                    print($0)
                })
                .addDisposableTo(rx.disposeBag)
        }
    }
    

    or

       func creatObservable() {        
            self.rx.tapGesture()
                .takeUntil(rx.deallocated)
                .subscribe({
                    print($0)
                })
        }
    

    How can i release the resource in time in case it prevent the dealloc of the custom view?

    opened by raymondCaptain 8
  • RxSwift/RxCocoa 4.5 compatibility

    RxSwift/RxCocoa 4.5 compatibility

    The dependencies in the podspec prevent it from being compatible with the latest versions of RxSwift and RxCoccoa:

    s.dependency 'RxSwift', '~> 4.4.0'
    s.dependency 'RxCocoa', '~> 4.4.0'
    

    Changing them to this would solve the problem:

    s.dependency 'RxSwift', '~> 4.4'
    s.dependency 'RxCocoa', '~> 4.4'
    
    opened by seanrucker 7
  • Bump tzinfo from 1.2.9 to 1.2.10

    Bump tzinfo from 1.2.9 to 1.2.10

    Bumps tzinfo from 1.2.9 to 1.2.10.

    Release notes

    Sourced from tzinfo's releases.

    v1.2.10

    TZInfo v1.2.10 on RubyGems.org

    Changelog

    Sourced from tzinfo's changelog.

    Version 1.2.10 - 19-Jul-2022

    Commits
    • 0814dcd Fix the release date.
    • fd05e2a Preparing v1.2.10.
    • b98c32e Merge branch 'fix-directory-traversal-1.2' into 1.2
    • ac3ee68 Remove unnecessary escaping of + within regex character classes.
    • 9d49bf9 Fix relative path loading tests.
    • 394c381 Remove private_constant for consistency and compatibility.
    • 5e9f990 Exclude Arch Linux's SECURITY file from the time zone index.
    • 17fc9e1 Workaround for 'Permission denied - NUL' errors with JRuby on Windows.
    • 6bd7a51 Update copyright years.
    • 9905ca9 Fix directory traversal in Timezone.get when using Ruby data source
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • a minimum deployment target of iOS 12.0

    a minimum deployment target of iOS 12.0

    I make xcframework by Carthage and integrate it in my project with this error:

    截屏2022-03-24 20 56 45

    this is my framework project, I wanna take a framework that contain Rx... to easy for use

    How can I set the minimum version like podSpec or another way to fix that?

    opened by ShenYj 3
  • Broken build on macOS after changes in 4.0.3

    Broken build on macOS after changes in 4.0.3

    Fixing the exclude path in Package.swift #126 actually broke the build on macOS.

    Since the extension in Pod/Classes/OSX/NSGestureRecognizer+Rx is not created, we end up getting an error in Pod/Classes/View+RxGesture.swift

    .../RxGesture/Pod/Classes/View+RxGesture.swift:98:38: value of type 'Reactive' (aka 'Reactive') has no dynamic member 'event' using key path from root type 'RxGestureRecognizer' (aka 'NSGestureRecognizer')

    We should probably remove the exclude config since we already filter out those files using #if canImport(AppKit) and there's currently no way of specifying supported platforms per target.

    opened by pakerwreah 0
Releases(4.0.4)
  • 4.0.1(Jan 23, 2021)

  • 4.0.0(Jan 5, 2021)

    • Support RxSwift 6
    • Prefix module typaliases with RxGesture to avoid conflicts with SwiftUI (or any other module):
      • ViewRxGestureView
      • GestureRecognizerRxGestureRecognizer
      • PointRxGesturePoint
      • etc...
    • Enhance custom gesture recognizers (ForceTouchGestureRecognizer and TouchDownGestureRecognizer)
    • Enhance example app
    Source code(tar.gz)
    Source code(zip)
  • 3.0.3(Apr 21, 2020)

  • 3.0.1(Oct 14, 2019)

  • 3.0.0(May 14, 2019)

  • 2.2.0(Apr 11, 2019)

  • 2.0.1(Sep 26, 2018)

  • 2.0.0(Sep 22, 2018)

    • Adds compatibility with Xcode 10.0 and Swift 4.2
    • Uses simpler and more consistant syntax. No more properties in constructors parameters. Please use the trailing closure to configure the gesture recognizer if needed.
    • Adds 2 new custom gesture recognizers on iOS:
      • .forceTouch() → it exposes the force value of underlying UITouch objects
      • .touchDown() → it exposes all UITouch objects involved in the gesture
    • Adds readable typealiases to represent an observable gesture recognizer. Ex: Observable<UITapGestureRecognizer>TapObservable
    • Enhances example projects
    • Adds Mojave dark mode support for OSX example app
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Oct 22, 2017)

  • 1.2.0(Oct 19, 2017)

  • 1.1.1(Aug 25, 2017)

  • 1.1.0(Aug 18, 2017)

    RxGestureRecognizerDelegate

    This release introduces a new customizable delegate RxGestureRecognizerDelegate that replaces the old PermissiveGestureRecognizerDelegate. It allows you to customize every delegate method using a policy.

    See documentation for more information: https://github.com/RxSwiftCommunity/RxGesture#delegate-customization

    Other library changes

    • fix carthage on macOS target (fix #48 #54 #55)
    • set iOS minimum target to iOS 8.0 (fix #17)
    • update to RxSwift 3.6.0

    Examples changes

    • fix a reentrancy issue in iOS example
    • fix the anchor point for transform in macOS example
    • fix a retain cycle in both examples
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Apr 13, 2017)

  • 1.0.0(Feb 20, 2017)

    This release comes with a global refactor. Amongst all changes you'll find :

    • new and richer API
    • support of all native gesture recognizers for iOS and macOS (tap, pinch, pan, screen-edge-pan, rotation, long-press, click, etc...)
    • open to third party gesture recognizers : you're now able to make your own gesture recognizers working with RxGesture, right into your project.
    • support for gesture recognizer configuration : you're now able to configure all properties of a gesture recognizer
    • smarter handling of continuous gestures (pan, pinch, rotate)

    Check the README.md file and the Example project for more informations.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Oct 25, 2016)

  • 0.1.7(Oct 9, 2016)

  • 0.1.6(Apr 5, 2016)

    Adds dragging and rotating, restructures how gestures are represented internally. Still needs lot of work on the OSX side but already features few gestures

    Source code(tar.gz)
    Source code(zip)
Owner
RxSwift Community
RxSwift ecosystem projects
RxSwift Community
A reactive wrapper built around UIImagePickerController.

RxMediaPicker RxMediaPicker is a RxSwift wrapper built around UIImagePickerController consisting in a simple interface for common actions like picking

RxSwift Community 180 Apr 24, 2022
RxSwift wrapper around the elegant HTTP networking in Swift Alamofire

RxAlamofire RxAlamofire is a RxSwift wrapper around the elegant HTTP networking in Swift Alamofire. Getting Started Wrapping RxSwift around Alamofire

RxSwift Community 1.6k Jan 3, 2023
A testable RxSwift wrapper around MultipeerConnectivity

A testable RxSwift wrapper around MultipeerConnectivity RxMultipeer is a RxSwift wrapper for MultipeerConnectivity. Using the adapter pattern, we can

RxSwift Community 69 Jul 5, 2022
Reactive Programming in Swift

Rx is a generic abstraction of computation expressed through Observable<Element> interface, which lets you broadcast and subscribe to values and other

ReactiveX 23.1k Jan 5, 2023
A Swift Reactive Programming Kit

ReactiveKit is a lightweight Swift framework for reactive and functional reactive programming that enables you to get into the reactive world today. T

Declarative Hub 1.2k Dec 29, 2022
Simple and lightweight Functional Reactive Coding in Swift for the rest of us

The simplest Observable<T> implementation for Functional Reactive Programming you will ever find. This library does not use the term FRP (Functional R

Jens Ravens 1.1k Jan 3, 2023
Reactive Keyboard in iOS

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

RxSwift Community 1.4k Dec 29, 2022
Reactive WebSockets

RxWebSocket Reactive extensions for websockets. A lightweight abstraction layer over Starscream to make it reactive. Installation RxWebSocket is avail

Flávio Caetano 57 Jul 22, 2022
RxReduce is a lightweight framework that ease the implementation of a state container pattern in a Reactive Programming compliant way.

About Architecture concerns RxReduce Installation The key principles How to use RxReduce Tools and dependencies Travis CI Frameworks Platform Licence

RxSwift Community 125 Jan 29, 2022
A Swift framework for reactive programming.

CwlSignal An implementation of reactive programming. For details, see the article on Cocoa with Love, CwlSignal, a library for reactive programming. N

Matt Gallagher 304 Oct 25, 2022
A powerful, minimal and composable architecture for building reactive iOS apps with SwiftUI or UIKit

SourceArchitecture A simple yet powerful framework for reactive programming with only a minimal optimized set of types. Sources are self-contained, hi

Daniel Hall 6 Nov 1, 2022
Swift Reactive Programming.

ReactKit Swift Reactive Programming. How to install See Wiki page. Example For UI Demo, please see ReactKit/ReactKitCatalog. Key-Value Observing // cr

ReactKit 1.2k Nov 6, 2022
Super Simple Pager with RxSwift extension

SSPager Super Simple Pager Example To run the example project, clone the repo, and run pod install from the SSPagerExample directory first. Installati

9oya 4 Jul 10, 2022
RxSwift extentions for Swift optionals and "Occupiable" types

RxOptional RxSwift extentions for Swift optionals and "Occupiable" types. Usage All operators are available on Driver as well unless otherwise marked.

Thane Gill 8 Jun 28, 2020
RxSwift bindings for Permissions API in iOS.

RxPermission RxSwift bindings for Permission API that helps you with Permissions in iOS. Installation RxPermission is available through CocoaPods. I c

Luke 230 Dec 27, 2022
RxSwift extension for RealmSwift's types

RxRealm This library is a thin wrapper around RealmSwift ( Realm Docs ). Table of contents: Observing object collections Observing a single object Wri

RxSwift Community 1.1k Jan 6, 2023
iOS & OSX Bluetooth library for RxSwift

RxBluetoothKit is a Bluetooth library that makes interaction with BLE devices much more pleasant. It's backed by RxSwift and CoreBluetooth and it prov

Polidea 1.3k Dec 16, 2022
Handy RxSwift extensions on NSObject, including rx.disposeBag.

NSObject+Rx If you're using RxSwift, you've probably encountered the following code more than a few times. class MyObject: Whatever { let disposeBag

RxSwift Community 625 Dec 12, 2022
RxSwift extensions for Core Data

RxCoreData Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements Xcode 9.0 Swift 4.0

RxSwift Community 164 Oct 14, 2022