material-motion / material-motion-swift

A toolkit for building responsive motion using Core Animation.
Apache License 2.0
1.42k stars 79 forks source link

Maintain consistency between ReactiveUIView's properties and its backing ReactiveCALayer's. #40

Closed chuga closed 7 years ago

chuga commented 7 years ago

For example, if I write to a ReactiveUIView's backing ReactiveCALayer's position property the ReactiveUIView's center property should be updated as well (and vice versa).

A solution might be to use the layer's property directly if we can, and write a wrapper around it when it's not a 1:1 map:

public lazy var alpha: ReactiveProperty<CGFloat> = {
    return self.reactiveLayer.opacity
}()
public lazy var center: ReactiveProperty<CGPoint> = {
    let view = self.view
    let property = ReactiveProperty(initialValue: view.center,
                                    write: {
                                      // TODO: Adjust depending on anchor point
                                      self.reactiveLayer.position.value = $0
                                    }, coreAnimation: {event in
                                      self.reactiveLayer.position.coreAnimation(event) })
    let subscription = self.reactiveLayer.position.asStream().subscribe(next: { position in
      // TODO: Adjust depending on anchor point
      if position != property.value {
        property.value = position
      }
    }, state: { _ in }, coreAnimation: { _ in })
    self.subscriptions.append(subscription)
    return property
}()
jverkoey commented 7 years ago

For now I've simply removed the duplicated properties in order to minimize likelihood of overlap. We'll recommend animating the layer properties only.