要运行示例项目,请克隆 repo,在 Example 文件夹中打开 RxGesture.xcworkspace
。
您可能需要先从 Example 目录运行 pod install
。
RxGesture 允许您轻松地将任何视图转换为可点击或可滑动控件,如下所示:
view.rx
.tapGesture()
.when(.recognized)
.subscribe(onNext: { _ in
//react to taps
})
.disposed(by: stepBag)
您还可以响应多个手势。例如,要关闭照片预览,您可能希望在用户点击它、或向上或向下滑动时执行此操作
view.rx
.anyGesture(.tap(), .swipe([.up, .down]))
.when(.recognized)
.subscribe(onNext: { _ in
//dismiss presented photo
})
.disposed(by: stepBag)
rx.gesture
定义为 Observable<G>
,其中 G
是手势识别器的实际类型,因此它发出的是手势识别器本身 (如果您想调用像 asLocation(in view:)
或 asTranslation(in view:)
这样的方法,这将非常有用)
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>
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>
ℹ️ 如果您单独使用手势识别器,则首选使用 view.rx.fooGesture()
语法而不是 view.rx.anyGesture(.foo())
,因为它返回具体的 UIGestureRecognizer
子类,并避免您在 subscribe()
中进行类型转换。
默认情况下,手势识别器的状态没有过滤器。 这意味着您将始终收到一个带有手势识别器初始状态的第一个事件(几乎总是 .possible
)。
以下是每种手势的首选状态(iOS 和 macOS)
类型 | 状态 |
---|---|
.tap() .click() .rightClick() .swipe() |
.recognized |
.longPress() .press() |
.began |
.pan() .pinch() .rotation() .magnification() .screenEdgePan() |
.began .changed .ended |
您通常使用 .when()
运算符过滤状态
view.rx.tapGesture().when(.recognized)
view.rx.panGesture().when(.began, .changed, .ended)
如果您一次观察多个手势,如果您想针对所有手势识别器过滤相同的状态,您可以使用 .when()
运算符,或者使用元组语法进行单独过滤
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)
演示应用程序包含所有识别器的示例 ➡️ iOS, macOS.
每个手势识别器都有一个默认的 RxGestureRecognizerDelegate
。它允许您使用策略自定义每个委托方法
.always
将向相应的委托方法返回 true
.never
将向相应的委托方法返回 false
.custom
接受一个关联的闭包,该闭包将被执行以向相应的委托方法返回值以下是可用的策略及其对应的委托方法
beginPolicy -> gestureRecognizerShouldBegin(:_)
touchReceptionPolicy -> gestureRecognizer(_:shouldReceive:)
selfFailureRequirementPolicy -> gestureRecognizer(_:shouldBeRequiredToFailBy:)
otherFailureRequirementPolicy -> gestureRecognizer(_:shouldRequireFailureOf:)
simultaneousRecognitionPolicy -> gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
eventRecognitionAttemptPolicy -> gestureRecognizer(_:shouldAttemptToRecognizeWith:) // macOS only
pressReceptionPolicy -> gestureRecognizer(_:shouldReceive:) // iOS only
可以在配置闭包中自定义此委托
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
}
})
可以在 RxGestureRecognizerDelegate.swift
中找到默认值。
您还可以用您自己的委托替换默认委托,或者将其删除。
view.rx.tapGesture { [unowned self] gestureRecognizer, delegate in
gestureRecognizer.delegate = nil
// or
gestureRecognizer.delegate = self
}
此库依赖于 RxSwift 和 RxCocoa。
添加到 Podfile
pod "RxGesture"
$ pod install
添加到 Cartfile
github "RxSwiftCommunity/RxGesture" ~> 3.0
$ carthage update
RxSwift Slack 频道中的每个人 💯
RxGesture 在 MIT 许可下可用。 有关更多信息,请参见 LICENSE 文件。