Skip to content

Instantly share code, notes, and snippets.

@loganwright
Last active February 1, 2016 20:03
Show Gist options
  • Save loganwright/05c224231feac477f56c to your computer and use it in GitHub Desktop.
Save loganwright/05c224231feac477f56c to your computer and use it in GitHub Desktop.
GestureMulticast in case you might need it
public struct Weak<T where T : AnyObject> {
public weak var value: T?
public init(_ value: T) {
self.value = value
}
}
public protocol Multicast : class {
typealias Delegate: AnyObject
var delegateReferences: [Weak<Delegate>] { get set }
}
public extension Multicast {
var delegates: [Delegate] {
let existing = delegateReferences.flatMap { $0.value }
if existing.count != delegateReferences.count {
delegateReferences = existing.map { Weak($0) }
}
return existing
}
func add(delegate: Delegate) {
delegateReferences.append(Weak(delegate))
}
func remove(shouldDelete: Delegate -> Bool) {
delegateReferences = delegates
.filter(not(shouldDelete))
.map(Weak.init)
}
}
final class GestureMulticast: NSObject, Multicast, UIGestureRecognizerDelegate {
typealias Delegate = UIGestureRecognizerDelegate
var delegateReferences: [Weak<Delegate>] = []
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
return delegateReferences
.flatMap { $0.value?.gestureRecognizerShouldBegin?(gestureRecognizer) }
.reduce(true, combine: reduceWithPrecedenceFalse)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return delegateReferences
.flatMap { $0.value?.gestureRecognizer?(gestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer: otherGestureRecognizer) }
.reduce(false, combine: reduceWithPrecedenceTrue)
}
//
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOfGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return delegateReferences
.flatMap { $0.value?.gestureRecognizer?(gestureRecognizer, shouldRequireFailureOfGestureRecognizer: otherGestureRecognizer) }
.reduce(false, combine: reduceWithPrecedenceTrue)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailByGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return delegateReferences
.flatMap { $0.value?.gestureRecognizer?(gestureRecognizer, shouldBeRequiredToFailByGestureRecognizer: otherGestureRecognizer) }
.reduce(false, combine: reduceWithPrecedenceTrue)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
return delegateReferences
.flatMap { $0.value?.gestureRecognizer?(gestureRecognizer, shouldReceiveTouch: touch) }
.reduce(true, combine: reduceWithPrecedenceFalse)
}
@available(iOS 9.0, *)
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceivePress press: UIPress) -> Bool {
return delegateReferences
.flatMap { $0.value?.gestureRecognizer?(gestureRecognizer, shouldReceivePress: press) }
.reduce(true, combine: reduceWithPrecedenceFalse)
}
/**
If either is false, is false
*/
private func reduceWithPrecedenceFalse(one: Bool, two: Bool) -> Bool {
if !one || !two {
return false
} else {
return true
}
}
/**
If either is true, is true
*/
private func reduceWithPrecedenceTrue(one: Bool, two: Bool) -> Bool {
if one || two {
return true
} else {
return false
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment