Issue #104

I like extensions, and I like to group them under 1 common property to easily access. This also makes it clear that these all belong to the same feature and not to confuse with Apple properties.

This is how I do it in Anchor and On

activate(
  a.anchor.top.left,
  b.anchor.top.right,
  c.anchor.bottom.left,
  d.anchor.bottom.right
)
textField.on.text { text in
  print("textField text has changed")
}

textField.on.didEndEditing { text in
  print("texField has ended editing")
}

Generic extension

For On, it is a bit tricky as it needs to adapt to different NSObject subclasses. And to make auto completion work, meaning that each type of subclass gets its own function hint, we need to use generic and associatedtype protocol.

You can take a look at Container and OnAware

public class Container<Host: AnyObject>: NSObject {
  unowned let host: Host

  init(host: Host) {
    self.host = host
  }
}
public protocol OnAware: class {
  associatedtype OnAwareHostType: AnyObject

  var on: Container<OnAwareHostType> { get }
}

RxCocoa

RxSwift has its RxCocoa that does this trick too, so that you can just declare

button.rx.tap
textField.rx.text
alertAction.rx.isEnabled

The power lies in the struct Reactive and ReactiveCompatible protocol

public struct Reactive<Base> {
    /// Base object to extend.
    public let base: Base

    /// Creates extensions with base object.
    ///
    /// - parameter base: Base object.
    public init(_ base: Base) {
        self.base = base
    }
}

public protocol ReactiveCompatible {
    /// Extended type
    associatedtype CompatibleType

    /// Reactive extensions.
    static var rx: Reactive<CompatibleType>.Type { get set }

    /// Reactive extensions.
    var rx: Reactive<CompatibleType> { get set }
}

extension ReactiveCompatible {
    /// Reactive extensions.
    public static var rx: Reactive<Self>.Type {
        get {
            return Reactive<Self>.self
        }
        set {
            // this enables using Reactive to "mutate" base type
        }
    }

    /// Reactive extensions.
    public var rx: Reactive<Self> {
        get {
            return Reactive(self)
        }
        set {
            // this enables using Reactive to "mutate" base object
        }
    }
}

Here UIButton+Rx you can see how it can be applied to UIButton

extension Reactive where Base: UIButton {
    
    /// Reactive wrapper for `TouchUpInside` control event.
    public var tap: ControlEvent<Void> {
        return controlEvent(.touchUpInside)
    }
}