Skip to content

Commit d31e82f

Browse files
refactor: using map instread of flatMap where appropriate, initializing ReactiveGestureReactor with UIGestureRecognizers
1 parent a5c3c26 commit d31e82f

File tree

2 files changed

+24
-39
lines changed

2 files changed

+24
-39
lines changed

functional-reactive-intuition/Project/RFP/ReactiveGestureReactor.swift

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,40 @@ class ReactiveGestureReactor: GestureReactor {
88

99
var delegate: GestureReactorDelegate?
1010

11-
private var timerCreator: ReactiveTimerCreator
11+
private let timerCreator: ReactiveTimerCreator
1212
private let disposeBag = DisposeBag()
1313

14-
private var panVariable: Variable<UIGestureRecognizerType?>
15-
private var rotateVariable: Variable<UIGestureRecognizerType?>
14+
private let panVariable: Variable<UIGestureRecognizerType>
15+
private let rotateVariable: Variable<UIGestureRecognizerType>
1616

17-
init(timerCreator: ReactiveTimerCreator) {
17+
init(timerCreator: ReactiveTimerCreator, gestureRecognizers: (UIGestureRecognizerType, UIGestureRecognizerType)) {
1818
self.timerCreator = timerCreator
19-
panVariable = Variable(nil)
20-
rotateVariable = Variable(nil)
21-
19+
self.panVariable = Variable(gestureRecognizers.0)
20+
self.rotateVariable = Variable(gestureRecognizers.1)
2221

2322
// FYI
2423
// Passing on the UIGesture at this point is dodgy as it's a reference
2524
// It's state will change and render our filter useless.
2625
// We therefore keep just the state in our observable buffers [.Began,.Began,.Ended]
27-
let rotateGesturesStartedEnded = rotateVariable.asObservable().filter { gesture in gesture?.state == .Began || gesture?.state == .Ended}.flatMap { (gesture) -> Observable<UIGestureRecognizerState> in
28-
return Observable.just(gesture!.state)
29-
}
3026

31-
let panGesturesStartedEnded = panVariable.asObservable().filter { gesture in gesture?.state == .Began || gesture?.state == .Ended}.flatMap { (gesture) -> Observable<UIGestureRecognizerState> in
32-
return Observable.just(gesture!.state)
33-
}
27+
let rotateGesturesStartedEnded = rotateVariable.asObservable().map { $0.state }.filter { $0 != .Began || $0 != .Ended }
28+
let panGesturesStartedEnded = panVariable.asObservable().map { $0.state }.filter { $0 != .Began || $0 != .Ended }
3429

3530
// Combine our latest .Began and .Ended from both Pan and Rotate.
36-
// If they are the same then return the same state. If not then return a Failed.
37-
let combineStartEndGestures = Observable.combineLatest(panGesturesStartedEnded, rotateGesturesStartedEnded) { (panState, rotateState) -> Observable<UIGestureRecognizerState> in
38-
39-
// If only one is .Ended, the result is .Ended too
40-
var state = UIGestureRecognizerState.Ended
41-
if panState == .Began && rotateState == .Began {
42-
state = .Began
43-
}
44-
45-
return Observable.just(state)
46-
}.switchLatest()
47-
48-
// several .Began events in a row are to be treated the same as a single one, it has just meaning if a .Ended is in between
49-
let distinceCombineStartEndGestures = combineStartEndGestures.distinctUntilChanged()
50-
31+
// If they are the same then return the same state. If not then return .Ended.
32+
let combinedGesture = Observable
33+
.combineLatest(rotateGesturesStartedEnded, panGesturesStartedEnded) { ($0, $1) }
34+
.map { ($0.0 == .Began && $0.1 == .Began)
35+
? UIGestureRecognizerState.Began
36+
: UIGestureRecognizerState.Ended
37+
}.distinctUntilChanged()
38+
// several .Began events in a row are to be treated the same as a single one, it has just meaning if a .Ended is in between
5139

5240
// condition: when both pan and rotate has begun
53-
let bothGesturesStarted = distinceCombineStartEndGestures.filter { (state) -> Bool in
54-
state == .Began
55-
}
41+
let bothGesturesStarted = combinedGesture.filter { $0 == .Began }
5642

5743
// condition: when both pan and rotate has Ended
58-
let bothGesturesEnded = distinceCombineStartEndGestures.filter { (state) -> Bool in
59-
state == .Ended
60-
}
44+
let bothGesturesEnded = combinedGesture.filter { $0 == .Ended }
6145

6246
// when bothGesturesStarted, do this:
6347
bothGesturesStarted.subscribeNext { [unowned self] _ in

functional-reactive-intuition/Project/RFP/ReactiveViewController.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,30 @@ class ReactiveViewController: UIViewController, SetStatus, GestureReactorDelegat
1717
@IBOutlet weak var centerXConstraint: NSLayoutConstraint! //For updating the position of the box when dragging
1818
@IBOutlet weak var centerYConstraint: NSLayoutConstraint!
1919

20-
private var gestureReactor: GestureReactor = ReactiveGestureReactor(timerCreator: { interval in ReactiveTimerFactory.reactiveTimer(interval: interval) })
20+
private var gestureReactor: GestureReactor!
2121

2222
private let disposeBag = DisposeBag()
2323

2424
override func viewDidLoad() {
2525
super.viewDidLoad()
2626

27-
gestureReactor.delegate = self
28-
2927
let pan = UIPanGestureRecognizer(target: self, action: "handlePan:")
3028
pan.delegate = self
3129
let rotate = UIRotationGestureRecognizer(target: self, action: "handleRotate:")
3230
rotate.delegate = self
33-
self.draggableView.gestureRecognizers = [pan, rotate]
31+
draggableView.gestureRecognizers = [pan, rotate]
3432

33+
gestureReactor = ReactiveGestureReactor(timerCreator: { interval in ReactiveTimerFactory.reactiveTimer(interval: interval) }, gestureRecognizers: (pan, rotate))
34+
gestureReactor.delegate = self
35+
3536

3637
///
3738
///
3839
/// Extra Code to manipulate move and rotate the subview.
3940
///
4041
/// Uses custom infix on CGPoint to '-' or '+' two together.
4142

42-
let panLocation = pan.rx_event.map { $0.locationInView(self.view) - self.view.center }
43+
let panLocation = pan.rx_event.map { [unowned self] in $0.locationInView(self.view) - self.view.center }
4344
panLocation.map { $0.x }
4445
.bindTo(self.centerXConstraint.rx_constant)
4546
.addDisposableTo(self.disposeBag)

0 commit comments

Comments
 (0)