Releases: material-motion/material-motion-swift
v2.0.0
This major release of Material Motion focuses includes improvements to the transitioning architecture, the reactive architecture, and new features on many of the interactions.
Breaking changes
• The IndefiniteObservable
dependency has been bumped to 4.0.0. View the release notes.
• The Metadata
and Inspectable
types have been removed from Material Motion. All related APIs have been simplified accordingly.
• The MotionRuntime.toGraphViz
API has been removed. There is no replacement API.
• Tossable
's init(system:draggable:)
has been removed. Use init(spring:draggable:)
instead.
• SelfDismissingTransition
's willPresent(fore:dismisser:)
is no longer a static method. Implement the method as an instance method instead.
• Transition
is now a class protocol. This means that only object-types can conform to Transition
.
• TransitionController
's dismisser
has been removed. All methods have been moved directly to the TransitionController object.
• Tween
's keyPositions
has been removed. Use offsets
instead.
• MotionRuntime
's interactions(for:filter:)
has been removed. Use interactions(ofType:for:)
instead.
New features
Reactive architecture
• Subscriptions no longer automatically unsubscribe when the Subscription object is released. Subscriptions will stay active for as long as the head of the stream is alive.
• Reactive types are now global and shared across all instances of MotionRuntime. You can use Reactive(object)
to fetch a cached reactive version of a supported type.
• MotionRuntime now supports a .get
for UISlider instances. This will return an Observable of the slider's value.
• New operator ignoreUntil
.
• New reactive variant of operator rubberBanded(outsideOf:maxLength:)
.
• New operator for float types toString(format:)
.
• New ReactiveScrollViewDelegate
API turns UIScrollViewDelegate events into observable streams.
For example, the delegate itself is an observable on the scroll view's content offset:
let delegate = ReactiveScrollViewDelegate()
scrollView.delegate = delegate
delegate.x().subscribeToValue { contentOffset in
print(contentOffset)
}
• New ReactiveButtonTarget
API for building reactive UIButtons.
• MotionRuntime
has a new API start(_:when:is:)
for starting interactions when another interaction reaches a given state.
• MotionRuntime
has a new isBeingManipulated
stream. This stream emits true when any Manipulable
interaction becomes active and false when all Manipulable
interactions come to rest.
Interactions
• MotionRuntime
now has a new isBeingManipulated
property that indicates whether any manipulation interaction is active.
Any interaction that conforms to the new Manipulation
type will affect the runtime's isBeingManipulated
property.
• Draggable
now has a resistance
property that can be used to create drag resistance beyond a draggable region.
draggable.resistance.perimeter.value = someRect
• Tween
has new properties for creating repeating animations: repeatCount
, repeatDuration
, and autoreverses
.
These properties directly map to the corresponding properties in Core Animation.
• TransitionTween
has new initializer values delayBefore
and delayAfter
.
delayBefore
is the delay used when transitioning forward. delayAfter
is the delay used when transitioning backward.
• The gesture property for gesture-based interactions is now optional. When nil, the interaction will do nothing.
This is primarily useful when building transitions that have optional interactivity.
Transitions
• New TransitionWithFallback
protocol allows transitions to swap themselves out for another transition instance.
• New TransitionWithPresentation
protocol allows transitions to customize their presentation using an iOS presentation controller. See the modal dialog case study for an example of using this new functionality.
• New TransitionWithTermination
protocol allows transitions to perform cleanup logic at the end of a transition.
• TransitionContext
's gestureRecognizers
is now settable. This makes it possible to add arbitrary gesture recognizers to a transition.
Source changes
- Attempt to reduce the flakiness of the PropertiesNotReleasedWhenDereferenced test. (Jeff Verkoeyen)
- Move fallback calculations to later in the transition lifecycle. (Jeff Verkoeyen)
- Add a backgroundColor property to Reactive+CALayer. (Jeff Verkoeyen)
- Add a defaultModalPresentationStyle API for transitions with presentation. (Jeff Verkoeyen)
- Allow TransitionWithPresentation to return nil for conditional presentation. (Jeff Verkoeyen)
- Add support for fallback transitions. (Jeff Verkoeyen)
- Make TransitionWithPresentation's method an instance method. (Jeff Verkoeyen)
- Don't attempt to slow down CASpringAnimation animations when slow-motion animations is enabled. (Jeff Verkoeyen)
- Add support for pre/post delay to TransitionTween. (Jeff Verkoeyen)
- Also slow down the beginTime for tweens when simulator slow motion is enabled. (Jeff Verkoeyen)
- When emitting Tweens with a delay, set the fill mode to backward. (Jeff Verkoeyen)
- Resolve new Xcode 8.3.2 warnings. (Jeff Verkoeyen)
- Remove all deprecated APIs in preparation for major release. (Jeff Verkoeyen)
- Remove Metadata. (Jeff Verkoeyen)
- Rename keyPositions to offsets (Eric Tang)
- Add a reactive button target type and an initial isHighlighted stream. (Jeff Verkoeyen)
- Add format support to the toString operator for numerical types. (Jeff Verkoeyen)
- Add runtime.get for UISlider instances. (Jeff Verkoeyen)
- Add reactive UILabel type with text property. (Jeff Verkoeyen)
- When using a transition with presentation, use the .custom modal presentation style. (Jeff Verkoeyen)
- Allow transition types to be instantiated and stored on the transition controller. (Jeff Verkoeyen)
- Remove the foreAlignmentEdge property from the transition controller. (Jeff Verkoeyen)
- Add support for customizing transition presentation. (Jeff Verkoeyen)
- Avoid excessive TransitionTween emissions when the transition direction changes. (Jeff Verkoeyen)
- Added ignoreUntil and simplified slop (Eric Tang)
- Added unit test (Eric Tang)
- Swap params for runtime.interactions() API (Eric Tang)
- Fix build failure. (Jeff Verkoeyen)
- Add a ReactiveScrollViewDelegate and replace usage of the MotionRuntime in the carousel demo. (Jeff Verkoeyen)
- Mark all MotionObservable subscribe methods with @discardableResult. (Jeff Verkoeyen)
- [Add a new ...
v1.3.0
Highlights:
- First contribution from Eric Tang adding support for
DispatchTimeInterval
initialization of time-based interactions and operators. - New visualization tools for streams.
- All gestural interactions can now be reactively enabled and disabled.
- Transitions APIs are evolving as we begin work on components. View the roadmap for more details.
Behavioral changes
• defaultTransitionSpringTension
and defaultTransitionSpringFriction
's values have been swapped to match the actual default values for tension and friction. These values were previously incorrectly reversed.
• Operators that do not support Core Animation will no longer throw runtime assertions when receiving Core Animation events. We have an open issue to explore nicer handling of operators and properties that do not support Core Animation.
New features
Runtime
• MotionRuntime now allows you to retrieve interactions associated with a given target with the new interactions(for:filter:)
API.
Example usage:
let draggables = runtime.interactions(for: view) { $0 as? Draggable }
Interactions
• PathTween
, Tween
, TransitionTween
each have a new convenience initializer that accepts the DispatchTimeInterval
enum, making it possible to specify explicit time units. Contributed by Eric Tang.
Example usage:
let tween = Tween<CGFloat>(duration: .milliseconds(300), values: [1, 0])
• Draggable
, Rotatable
, Scalable
, and DirectlyManipulable
now all conform to the Togglable
type, meaning they can be reactively enabled and disabled.
Example usage:
draggable.enabled.value = false // Disables the interaction
Operators
• delay(by:)
now accepts a DispatchTimeInterval
enum, making it possible to specify explicit time units. Contributed by Eric Tang.
let delayedStream = stream.delay(by: .seconds(1))
• toString()
transforms any stream into a string representation. This is part of our Reactive Controls milestone.
let stringStream = stream.toStream()
• visualize(in:)
allows you to display a stream's values and changes in your app with a new visualization overlay that appears atop your runtime's container view.
Example usage:
runtime.add(tossable, to: view) { $0.visualize(in: runtime.visualizationView) }
API changes
Runtime
• MotionRuntime's add
method now requires that targets conform to AnyObject. This will not affect any of the existing Interactions included with Material Motion. What this change means is that you can no longer build interactions that target non-object types.
Transitions
• TransitionController is now a pure Swift class type. This means TransitionController is no longer visible to Objective-C code. See #108 for our discussion on Objective-C support.
• TransitionController
now exposes a transitioningDelegate
property. TransitionController
no longer conforms to UIViewControllerTransitioningDelegate
.
// Before
viewController.transitioningDelegate = viewController.transitionController
// After
viewController.transitioningDelegate = viewController.transitionController.transitioningDelegate
Source changes
- Added convenience constructor that takes DispatchTimeInterval for duration (#107) (Eric Tang)
- Make ViewControllerDismisser a pure Swift class. (Jeff Verkoeyen)
- Make TransitionController a pure Swift class. (Jeff Verkoeyen)
- Add runtime.interactions(for:) API for fetching interactions associated with a given target. (Jeff Verkoeyen)
- Properly compare visualize's label text against the prefixed value string. (Jeff Verkoeyen)
- Add visualize operator and remove runtime.visualize. (Jeff Verkoeyen)
- Make all gestural interactions conform to Togglable. (Jeff Verkoeyen)
- Use a reasonable fallback when adding visualization views to the runtime container view. (Jeff Verkoeyen)
- Add runtime.visualize for visualizing values emitted by streams. (Jeff Verkoeyen)
- Remove runtime assertion when core animation events are sent to operators that don't support them. (Jeff Verkoeyen)
- Add toString operator. (Jeff Verkoeyen)
- Swap the default transition tension/friction values to match the proper variable names. (Jeff Verkoeyen)
API changes
Auto-generated by running:
apidiff origin/stable release-candidate swift MaterialMotion.xcworkspace MaterialMotion
MotionRuntime
new method: interactions(for:filter:)
in MotionRuntime
modified method: add(_:to:constraints:)
in MotionRuntime
: targets must now conform to AnyObject.
new var: visualizationView
in MotionRuntime
New operators
new method: delay(by:)
in MotionObservableConvertible
new method: toString()
in MotionObservableConvertible
new method: visualize(_:in:)
in MotionObservableConvertible
Interactions
DirectlyManipulable
modified class: DirectlyManipulable
Type of change: | Declaration |
---|---|
From: | public final class DirectlyManipulable : NSObject, Interaction, Stateful |
To: | public final class DirectlyManipulable : NSObject, Interaction, Togglable, Stateful |
Draggable
modified class: Draggable
Type of change: | Declaration |
---|---|
From: | public final class Draggable : Gesturable<UIPanGestureRecognizer>, Interaction, Stateful |
To: | public final class Draggable : Gesturable<UIPanGestureRecognizer>, Interaction, Togglable, Stateful |
Gesturable
new var: enabled
in Gesturable
PathTween
new method: init(duration:path:system:timeline:)
in PathTween
Rotatable
modified class: Rotatable
Type of change: | Declaration |
---|---|
From: | public final class Rotatable : Gesturable<UIRotationGestureRecognizer>, Interaction, Stateful |
To: | public final class Rotatable : Gesturable<UIRotationGestureRecognizer>, Interaction, Togglable, Stateful |
Scalable
modified class: Scalable
Type of change: | Declaration |
---|---|
From: | public final class Scalable : Gesturable<UIPinchGestureRecognizer>, Interaction, Stateful |
To: | public final class Scalable : Gesturable<UIPinchGestureRecognizer>, Interaction, Togglable, Stateful |
Tween
new method: init(duration:values:system:timeline:)
in Tween
TransitionTween
new method: init(duration:forwardValues:direction:forwardKeyPositions:system:timeline:)
in TransitionTween
Transitions
TransitionController
modified class: TransitionController
Type of change: | Declaration |
---|---|
From: | public final class TransitionController : NSObject |
To: | public final class TransitionController |
new var: transitioningDelegate
in TransitionController
ViewControllerDismisser
new var: gestureRecognizers
in ViewControllerDismisser
v1.2.1
This is a patch release resolving a crashing bug when runtime.shouldVisualizeMotion
was enabled and an ArcMove
interaction was added to a view without a parent.
Source changes
v1.2.0
This minor release introduces a new operator, startWith
, which is meant to replace the initialValue
operator.
New features
startWith operator
The new startWith
operator replaces initialValue
and behaves slightly differently: startWith
returns a memory stream, which is a stream that stores the last value it received and emits it upon subscription. What this means is that the provided initial value will only be emitted once, ever, and that the resulting stream is guaranteed to emit a value on subscription.
You can use startWith to take a stream that may not initially emit values (like a gesture stream) and prime it with an initial value. For example, we use startWith in the "How to use reactive constraints" example in order to ensure that our axis line property is primed with a value.
let axisCenterX = runtime.get(axisLine.layer).position.x()
runtime.add(Draggable(), to: exampleView) { $0
.startWith(exampleView.layer.position)
.xLocked(to: axisCenterX)
}
runtime.add(Draggable(), to: axisLine) { $0.yLocked(to: axisLine.layer.position.y) }
New deprecations
initialValue(_:)
has been deprecated in favor of the newstartWith(_:)
operator.
Source changes
- Deprecate initialValue and provide startWith as a replacement. (Jeff Verkoeyen)
- Renamed normalized.swift to normalizedBy.swift. (Jeff Verkoeyen)
- Rename unit test file rewriteTo.swift to rewriteToTests.swift. (Jeff Verkoeyen)
API changes
Auto-generated by running:
apidiff origin/stable release-candidate swift MaterialMotion.xcworkspace MaterialMotion
MotionObservableConvertible
new method: startWith(_:)
in MotionObservableConvertible
deprecated method: initialValue(_:)
in MotionObservableConvertible
: Use startWith(_:)
instead.
Non-source changes
- Fix README example. (Jeff Verkoeyen)
- Fix typo. (Jeff Verkoeyen)
v1.1.0
This is our first minor release. It includes two new interactions and improvements to APIs for the common cases.
Behavioral changes
- TransitionSpring's configuration now defaults to Core Animation's default values. If you prefer to continue using the original Spring defaults you can use the following snippet:
spring.tension.value = defaultSpringTension
spring.friction.value = defaultSpringFriction
spring.mass.value = defaultSpringMass
spring.suggestedDuration.value = 0
New deprecations
- Tossable's
init(system:draggable:)
is deprecated in favor ofinit(spring:draggable:)
.
New features
New interactions: ChangeDirection
and SlopRegion
.
Gesturable interactions can now be initialized with a sequence of gesture recognizers. This makes it easier to create gesturable interactions in transitions where the gesture recognizers are provided as a set.
Spring's system now defaults to Core Animation.
There is a new API for getting a gesture recognizer delegate that's able to coordinate a "drag to dismiss" transition with a vertical scroll view.
let pan = UIPanGestureRecognizer()
pan.delegate = transitionController.dismisser.topEdgeDismisserDelegate(for: scrollView)
Source changes
- Store interactions before adding them so that order is maintained when interactions add other interactions. (Jeff Verkoeyen)
- Avoid over-completion of chained property animations. (Jeff Verkoeyen)
- Fix bug causing properties-chained-to-properties to not animate correctly. (Jeff Verkoeyen)
- Add SlopRegion interaction. (Jeff Verkoeyen)
- Add topEdgeDismisserDelegate API to ViewControllerDismisser. (Jeff Verkoeyen)
- Add Gesturable convenience initializer for extracting the first gesture recognizer from a sequence of gesture recognizers. (Jeff Verkoeyen)
- Rename ChangeDirectionOnRelease(of:) to ChangeDirection(withVelocityOf:) (Jeff Verkoeyen)
- Fix crashing bug when connecting properties to one another. (Jeff Verkoeyen)
- Add ChangeDirectionOnRelease interaction. (Jeff Verkoeyen)
- Make TransitionSpring and Spring T type conform to Subtractable so that coreAnimation can be set as the default system. (Jeff Verkoeyen)
- TransitionSpring configuration now defaults to Core Animation configuration defaults. (Jeff Verkoeyen)
API changes
Auto-generated by running:
apidiff origin/stable release-candidate swift MaterialMotion.xcworkspace MaterialMotion
New global constants
new global var: defaultTransitionSpringFriction
new global var: defaultTransitionSpringSuggestedDuration
new global var: defaultTransitionSpringTension
new global var: defaultTransitionSpringMass
New interactions
new class: ChangeDirection
new class: SlopRegion
Modified interactions
Gesturable
Affects Draggable
, Rotatable
, and Scalable
.
new method: init(withFirstGestureIn:)
in Gesturable
Spring
Type of change: | Declaration |
---|---|
From: | public class Spring<T> : Interaction, Togglable, Stateful where T : Zeroable |
To: | public class Spring<T> : Interaction, Togglable, Stateful where T : Subtractable, T : Zeroable |
modified method: init(threshold:system:)
in Spring
Type of change: | Declaration |
---|---|
From: | public init(threshold: CGFloat, system: @escaping SpringToStream<T>) |
To: | public init(threshold: CGFloat = 1, system: @escaping SpringToStream<T> = coreAnimation) |
Tossable
modified method: init(spring:draggable:)
in Tossable
Type of change: | Declaration |
---|---|
From: | public init(spring: Spring<CGPoint>, draggable: Draggable = Draggable()) |
To: | public init(spring: Spring<CGPoint> = Spring(), draggable: Draggable = Draggable()) |
deprecated method: init(system:draggable:)
in Tossable
. Use init(spring:draggable:)
instead.
TransitionSpring
modified class: TransitionSpring
Type of change: | Declaration |
---|---|
From: | public final class TransitionSpring<T> : Spring<T> where T : Zeroable |
To: | public final class TransitionSpring<T> : Spring<T> where T : Subtractable, T : Zeroable |
modified method: init(back:fore:direction:threshold:system:)
in TransitionSpring
Type of change: | Declaration |
---|---|
From: | public init(back backwardDestination: T, fore forwardDestination: T, direction: ReactiveProperty<TransitionDirection>, threshold: CGFloat, system: @escaping SpringToStream<T>) |
To: | public init(back backwardDestination: T, fore forwardDestination: T, direction: ReactiveProperty<TransitionDirection>, threshold: CGFloat = default, system: @escaping SpringToStream<T> = default) |
Transitions
ViewControllerDismisser
new method: topEdgeDismisserDelegate(for:)
in ViewControllerDismisser
Stream changes
new var: onCompletion
in CoreAnimationChannelAdd
removed var: onCompletion
in CoreAnimationChannelAdd
Non-source changes
- Modify the PushBackTransition example to use connected properties instead of multiple springs. (Jeff Verkoeyen)
- Simplify the interactive push back transition example. (Jeff Verkoeyen)
- Add syntax highlighting languages to the README. (Jeff Verkoeyen)
- Add example Podfile to the README. (Jeff Verkoeyen)
v1.0.0
Initial stable release of Material Motion. Includes:
- Interactions with constraint support.
- Runtime visualization using graphviz.
- Many case studies in the Catalog app.
- A Swift playground.
Source changes
- Reintroduce property core animation event forwarding. (Jeff Verkoeyen)
- And one last missing import. (Jeff Verkoeyen)
- Add one more missing import. (Jeff Verkoeyen)
- Add more missing UIKit imports. (Jeff Verkoeyen)
- Add missing import statements throughout the codebase. (Jeff Verkoeyen)
- Slow down Core Animation animations when simulator slow motion animations is enabled. (Jeff Verkoeyen)
- Add default coordinate space to SetPositionOnTap initializer. (Jeff Verkoeyen)
- Rename TransitionContext.Direction to TransitionDirection. (Jeff Verkoeyen)
- Add x-/yLockedTo tests. (Jeff Verkoeyen)
- Use a different y value for normalize tests. (Jeff Verkoeyen)
- Rename threshold event to threshold side and drop the -when prefix. (Jeff Verkoeyen)
- Add threshold tests. (Jeff Verkoeyen)
- Add rubberBanded tests. (Jeff Verkoeyen)
- Remove subtractedFrom operator. (Jeff Verkoeyen)
- Add offsetBy and scaledBy tests. (Jeff Verkoeyen)
- Add normalize tests. (Jeff Verkoeyen)
- Add anchorPointAdjustment tests. (Jeff Verkoeyen)
- Fix bug causing Tween never to come to rest. (Jeff Verkoeyen)
- Add rewrite tests. (Jeff Verkoeyen)
- Add merge tests. (Jeff Verkoeyen)
- Add inverted tests. (Jeff Verkoeyen)
- Add distanceFrom tests and improve reactive implementation. (Jeff Verkoeyen)
- Add initialValue tests. (Jeff Verkoeyen)
- Remove unnecessary testing imports. (Jeff Verkoeyen)
- Add valve tests. (Jeff Verkoeyen)
- Add upper-/lowerBound tests. (Jeff Verkoeyen)
- Add delay tests. (Jeff Verkoeyen)
- Add dedupe tests. (Jeff Verkoeyen)
- Add slop tests. (Jeff Verkoeyen)
- Default untyped integer literals to be CGFloat ReactiveProperties. (Jeff Verkoeyen)
- Rearrange the operator unit tests to match the source file layout. (Jeff Verkoeyen)
- Add Addable/Subtractable tests. (Jeff Verkoeyen)
- Add _remember tests. (Jeff Verkoeyen)
- Add Core Animation _map tests. (Jeff Verkoeyen)
- Add TransitionTween interaction. (Jeff Verkoeyen)
- Add support for reactively re-animating Tweens when values or keyPositions changes. (Jeff Verkoeyen)
- Make TransitionContext.Direction conform to Invertible. (Jeff Verkoeyen)
- Add rewrite operator that accepts an observable. (Jeff Verkoeyen)
- Add Invertible type and general-purpose inverted operator. (Jeff Verkoeyen)
- Add support for additive Core Animation tweens. (Jeff Verkoeyen)
- Make additive calculations more generic in preparation for keyframe additive animation support. (Jeff Verkoeyen)
- Ensure that Gesturable interactions that use an existing gesture recognizer prime the initial state. (Jeff Verkoeyen)
- Remove superfluous Equatable conformity in coreAnimationSpringToStream. (Jeff Verkoeyen)
- Add width/height reactive properties to CALayer. (Jeff Verkoeyen)
- Make all classes final that can be. (Jeff Verkoeyen)
- Add NoConstraints typealias for interactions that don't support constraints. (Jeff Verkoeyen)
- Add draggable.finalVelocity API. (Jeff Verkoeyen)
- Rename runtime.disable to runtime.toggle. (Jeff Verkoeyen)
- Use primary/secondary colors for metadata readouts. (Jeff Verkoeyen)
- Simulate atRest/active eventing for tap gestures so that they can be used to start animations. (Jeff Verkoeyen)
- Resolve Xcode 8.3 warnings. (Jeff Verkoeyen)
- Add Tween example and hacky runtime.start(when) mechanism. (Jeff Verkoeyen)
- Add Scalable/Tossable interaction demos and fix bug in Tossable state reporting. (Jeff Verkoeyen)
- Update name to MaterialMotion. (Jeff Verkoeyen)
- Provide a default for ArcMove's initializer. (Jeff Verkoeyen)
- Add rotatable example and make Rotatable/Scalable conform to Stateful. (Jeff Verkoeyen)
- [Remove old demos and general usage of POP in preparation for ...