Skip to content
This repository has been archived by the owner on Aug 13, 2021. It is now read-only.

Commit

Permalink
Merge branch 'release-candidate' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff Verkoeyen committed Apr 12, 2017
2 parents e7f3825 + 6565de5 commit 959ecd2
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 59 deletions.
4 changes: 2 additions & 2 deletions .jazzy.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module: MaterialMotion
module_version: 1.1.0
module_version: 1.2.0
sdk: iphonesimulator
xcodebuild_arguments:
- -workspace
- MaterialMotion.xcworkspace
- -scheme
- MaterialMotion
github_url: https://github.com/material-motion/material-motion-swift
github_file_prefix: https://github.com/material-motion/material-motion-swift/tree/v1.1.0
github_file_prefix: https://github.com/material-motion/material-motion-swift/tree/v1.2.0
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
# 1.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](https://github.com/staltz/xstream#memorystream), 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 once, ever, and that the resulting stream is guaranteed to emit a value on subscription.

You can use startWith to turn 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.

<img src="assets/constraints.gif" />

```swift
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 new `startWith(_:)` operator.

## Source changes

* [Deprecate initialValue and provide startWith as a replacement.](https://github.com/material-motion/material-motion-swift/commit/2a5df59861c4ec0f737e2bc7e38d8bb0801e8e66) (Jeff Verkoeyen)
* [Renamed normalized.swift to normalizedBy.swift.](https://github.com/material-motion/material-motion-swift/commit/8ff079b6ba1322f3fae47a6f2eb2d72bc2158203) (Jeff Verkoeyen)
* [Rename unit test file rewriteTo.swift to rewriteToTests.swift.](https://github.com/material-motion/material-motion-swift/commit/0d81c70185865008282ee717e1bd7404227befe0) (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.](https://github.com/material-motion/material-motion-swift/commit/21ab8263cc0f1bf0b0b7724954b55d9147c480d1) (Jeff Verkoeyen)
* [Fix typo.](https://github.com/material-motion/material-motion-swift/commit/16fbf643a4873c4bc79da83119ed735168070b60) (Jeff Verkoeyen)

# 1.1.0

This is our first minor release. It includes two new interactions and improvements to APIs for the common cases.
Expand Down
2 changes: 1 addition & 1 deletion MaterialMotion.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "MaterialMotion"
s.summary = "Reactive motion driven by Core Animation."
s.version = "1.1.0"
s.version = "1.2.0"
s.authors = "The Material Motion Authors"
s.license = "Apache 2.0"
s.homepage = "https://github.com/material-motion/material-motion-swift"
Expand Down
4 changes: 2 additions & 2 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PODS:
- IndefiniteObservable (3.1.0):
- IndefiniteObservable/lib (= 3.1.0)
- IndefiniteObservable/lib (3.1.0)
- MaterialMotion (1.1.0):
- MaterialMotion (1.2.0):
- IndefiniteObservable (~> 3.0)

DEPENDENCIES:
Expand All @@ -17,7 +17,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
CatalogByConvention: be55c2263132e4f9f59299ac8a528ee8715b3275
IndefiniteObservable: 2789d61f487d8d37fa2b9c3153cc44d4447ff744
MaterialMotion: 6ee4d44d39b074686d603c26c20a5816afdb50cd
MaterialMotion: 4a4f155a35fce5e1dad7cc838719ef1c9c590dc6

PODFILE CHECKSUM: f503265a0d60526a0d28c96dd4bdcfb40fb562fc

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ runtime.add(arcMove, to: <#view#>)</code></pre></td>
<td align="center"><img src="assets/changedirection.gif" /></td>
<td><pre><code class="language-swift">ChangeDirection</code></pre></td>
<td><pre><code class="language-swift">runtime.add(ChangeDirection(withVelocityOf: gesture),
to: <#view#>)</code></pre></td>
to: <#direction#>)</code></pre></td>
</tr>
<tr>
<td align="center"><img src="assets/directlymanipulable.gif" /></td>
Expand Down Expand Up @@ -181,7 +181,7 @@ Makes use of: `Transition` and `Tween`.

<img src="assets/materialexpansion.gif" />

A Material Design transition using assymetric transformations.
A Material Design transition using asymetric transformations.

Makes use of: `Tween`.

Expand Down
Binary file added assets/constraints.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/HowToUseReactiveConstraintsExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class HowToUseReactiveConstraintsExampleViewController: ExampleViewController {

let axisCenterX = runtime.get(axisLine.layer).position.x()
runtime.add(Draggable(), to: exampleView) { $0
.initialValue(exampleView.layer.position)
.startWith(exampleView.layer.position)
.xLocked(to: axisCenterX)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
660DA3211E7A106D008F7401 /* TweenExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660DA3201E7A106D008F7401 /* TweenExample.swift */; };
6613A9DB1E832779004A3699 /* mergeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9DA1E832779004A3699 /* mergeTests.swift */; };
6613A9DD1E832913004A3699 /* rewriteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9DC1E832913004A3699 /* rewriteTests.swift */; };
6613A9DF1E8329DF004A3699 /* rewriteTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9DE1E8329DF004A3699 /* rewriteTo.swift */; };
6613A9DF1E8329DF004A3699 /* rewriteToTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9DE1E8329DF004A3699 /* rewriteToTests.swift */; };
6613A9E11E832B18004A3699 /* rewriteRangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9E01E832B18004A3699 /* rewriteRangeTests.swift */; };
6613A9E31E841461004A3699 /* anchorPointAdjustmentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9E21E841461004A3699 /* anchorPointAdjustmentTests.swift */; };
6613A9E71E84170B004A3699 /* normalizeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9E61E84170B004A3699 /* normalizeTests.swift */; };
6613A9E71E84170B004A3699 /* normalizedByTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9E61E84170B004A3699 /* normalizedByTests.swift */; };
6613A9E91E841856004A3699 /* offsetByTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9E81E841856004A3699 /* offsetByTests.swift */; };
6613A9EB1E84188D004A3699 /* scaledByTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9EA1E84188D004A3699 /* scaledByTests.swift */; };
6613A9ED1E841C04004A3699 /* rubberBandedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A9EC1E841C04004A3699 /* rubberBandedTests.swift */; };
Expand Down Expand Up @@ -63,7 +63,7 @@
6695129B1E830AE500D8868D /* lowerBoundTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6695129A1E830AE500D8868D /* lowerBoundTests.swift */; };
6695129D1E830B6E00D8868D /* upperBoundTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6695129C1E830B6E00D8868D /* upperBoundTests.swift */; };
6695129F1E830C0800D8868D /* valveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6695129E1E830C0800D8868D /* valveTests.swift */; };
669512A11E830E1900D8868D /* initialValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669512A01E830E1900D8868D /* initialValueTests.swift */; };
669512A11E830E1900D8868D /* startWithTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669512A01E830E1900D8868D /* startWithTests.swift */; };
66BD3CCB1E8046AD00AA413C /* MaterialExpansionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66BD3CCA1E8046AD00AA413C /* MaterialExpansionExample.swift */; };
66DDFD0D1E71F0F100AA46B7 /* DraggableExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DDFD0C1E71F0F100AA46B7 /* DraggableExample.swift */; };
66DDFD121E71F39700AA46B7 /* ExampleViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DDFD111E71F39700AA46B7 /* ExampleViews.swift */; };
Expand Down Expand Up @@ -102,10 +102,10 @@
660DA3201E7A106D008F7401 /* TweenExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TweenExample.swift; path = ../../TweenExample.swift; sourceTree = "<group>"; };
6613A9DA1E832779004A3699 /* mergeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = mergeTests.swift; sourceTree = "<group>"; };
6613A9DC1E832913004A3699 /* rewriteTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = rewriteTests.swift; sourceTree = "<group>"; };
6613A9DE1E8329DF004A3699 /* rewriteTo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = rewriteTo.swift; sourceTree = "<group>"; };
6613A9DE1E8329DF004A3699 /* rewriteToTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = rewriteToTests.swift; sourceTree = "<group>"; };
6613A9E01E832B18004A3699 /* rewriteRangeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = rewriteRangeTests.swift; sourceTree = "<group>"; };
6613A9E21E841461004A3699 /* anchorPointAdjustmentTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = anchorPointAdjustmentTests.swift; sourceTree = "<group>"; };
6613A9E61E84170B004A3699 /* normalizeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = normalizeTests.swift; sourceTree = "<group>"; };
6613A9E61E84170B004A3699 /* normalizedByTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = normalizedByTests.swift; sourceTree = "<group>"; };
6613A9E81E841856004A3699 /* offsetByTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = offsetByTests.swift; sourceTree = "<group>"; };
6613A9EA1E84188D004A3699 /* scaledByTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = scaledByTests.swift; sourceTree = "<group>"; };
6613A9EC1E841C04004A3699 /* rubberBandedTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = rubberBandedTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -150,7 +150,7 @@
6695129A1E830AE500D8868D /* lowerBoundTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = lowerBoundTests.swift; sourceTree = "<group>"; };
6695129C1E830B6E00D8868D /* upperBoundTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = upperBoundTests.swift; sourceTree = "<group>"; };
6695129E1E830C0800D8868D /* valveTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = valveTests.swift; sourceTree = "<group>"; };
669512A01E830E1900D8868D /* initialValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = initialValueTests.swift; sourceTree = "<group>"; };
669512A01E830E1900D8868D /* startWithTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = startWithTests.swift; sourceTree = "<group>"; };
66BD3CCA1E8046AD00AA413C /* MaterialExpansionExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MaterialExpansionExample.swift; path = ../../MaterialExpansionExample.swift; sourceTree = "<group>"; };
66DDFD0C1E71F0F100AA46B7 /* DraggableExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DraggableExample.swift; path = ../../DraggableExample.swift; sourceTree = "<group>"; };
66DDFD111E71F39700AA46B7 /* ExampleViews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleViews.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -276,18 +276,18 @@
669512921E8301D100D8868D /* dedupeTests.swift */,
669512961E8305AC00D8868D /* delayTests.swift */,
6605044D1E83146C009EDB8A /* distanceFromTests.swift */,
669512A01E830E1900D8868D /* initialValueTests.swift */,
66F2C3C81E83245800DD9728 /* invertedTests.swift */,
6695129A1E830AE500D8868D /* lowerBoundTests.swift */,
6613A9DA1E832779004A3699 /* mergeTests.swift */,
6613A9E61E84170B004A3699 /* normalizeTests.swift */,
6613A9E61E84170B004A3699 /* normalizedByTests.swift */,
6613A9E81E841856004A3699 /* offsetByTests.swift */,
6613A9DC1E832913004A3699 /* rewriteTests.swift */,
6613A9E01E832B18004A3699 /* rewriteRangeTests.swift */,
6613A9DE1E8329DF004A3699 /* rewriteTo.swift */,
6613A9DE1E8329DF004A3699 /* rewriteToTests.swift */,
6613A9EC1E841C04004A3699 /* rubberBandedTests.swift */,
6613A9EA1E84188D004A3699 /* scaledByTests.swift */,
6695128E1E82ED0900D8868D /* slopTests.swift */,
669512A01E830E1900D8868D /* startWithTests.swift */,
6613A9EE1E8420CE004A3699 /* thresholdTests.swift */,
6613A9F01E84214F004A3699 /* thresholdRangeTests.swift */,
6695129C1E830B6E00D8868D /* upperBoundTests.swift */,
Expand Down Expand Up @@ -656,7 +656,7 @@
6613A9F51E842FF5004A3699 /* yLockedToTests.swift in Sources */,
669512891E82E8CB00D8868D /* _rememberTests.swift in Sources */,
669512741E82E68900D8868D /* SubtractableTests.swift in Sources */,
6613A9DF1E8329DF004A3699 /* rewriteTo.swift in Sources */,
6613A9DF1E8329DF004A3699 /* rewriteToTests.swift in Sources */,
6613A9DD1E832913004A3699 /* rewriteTests.swift in Sources */,
6613A9DB1E832779004A3699 /* mergeTests.swift in Sources */,
6695129B1E830AE500D8868D /* lowerBoundTests.swift in Sources */,
Expand All @@ -666,9 +666,9 @@
6686F01C1E77293100F97CC4 /* MotionRuntimeTests.swift in Sources */,
669512931E8301D100D8868D /* dedupeTests.swift in Sources */,
6613A9F31E842F8B004A3699 /* xLockedToTests.swift in Sources */,
6613A9E71E84170B004A3699 /* normalizeTests.swift in Sources */,
6613A9E71E84170B004A3699 /* normalizedByTests.swift in Sources */,
6613A9EB1E84188D004A3699 /* scaledByTests.swift in Sources */,
669512A11E830E1900D8868D /* initialValueTests.swift in Sources */,
669512A11E830E1900D8868D /* startWithTests.swift in Sources */,
669512871E82E8CB00D8868D /* _mapTests.swift in Sources */,
6613A9EF1E8420CE004A3699 /* thresholdTests.swift in Sources */,
6695128B1E82E8CB00D8868D /* yTests.swift in Sources */,
Expand Down
File renamed without changes.
14 changes: 11 additions & 3 deletions src/operators/initialValue.swift → src/operators/startWith.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,19 @@ import Foundation
extension MotionObservableConvertible {

/**
Emits the provided value and then subscribes upstream and emits all subsequent values with no
modification.
Emits the provided value and then emits the values emitted by the upstream.

Helpful for priming a stream with an initial value.
The returned stream will cache the last value received and immediately emit it on subscription.
The returned stream is therefor guaranteed to always immediately emit a value upon subscription.
*/
public func startWith(_ value: T) -> MotionObservable<T> {
return MotionObservable(self.metadata.createChild(Metadata(#function, type: .constraint, args: [value]))) { observer in
observer.next(value)
return self.asStream().subscribeAndForward(to: observer).unsubscribe
}._remember()
}

@available(*, deprecated, message: "Use startWith() instead.")
public func initialValue(_ value: T) -> MotionObservable<T> {
return MotionObservable(self.metadata.createChild(Metadata(#function, type: .constraint, args: [value]))) { observer in
observer.next(value)
Expand Down
36 changes: 0 additions & 36 deletions tests/unit/operator/initialValueTests.swift

This file was deleted.

96 changes: 96 additions & 0 deletions tests/unit/operator/startWithTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
Copyright 2017-present The Material Motion Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import XCTest
import IndefiniteObservable
import MaterialMotion

class startWithTests: XCTestCase {

func testOverwrittenByReactivePropertyDefaultValue() {
let property = createProperty(withInitialValue: 0)

var values: [CGFloat] = []
let subscription = property.startWith(10).subscribeToValue { value in
values.append(value)
}

property.value = -10

XCTAssertEqual(values, [0, -10])

subscription.unsubscribe()
}

func testInitializedWithInitialValue() {
var valueObserver: MotionObserver<CGFloat>?
let observable = MotionObservable<CGFloat> { observer in
valueObserver = observer
return noopDisconnect
}

var values: [CGFloat] = []
let subscription = observable.startWith(10).subscribeToValue { value in
values.append(value)
}

valueObserver?.next(50)

XCTAssertEqual(values, [10, 50])

subscription.unsubscribe()
}

func testAdditionalSubscriptionsReceiveLatestValue() {
var valueObserver: MotionObserver<CGFloat>?
let observable = MotionObservable<CGFloat> { observer in
valueObserver = observer
return noopDisconnect
}

let stream = observable.startWith(10)

let subscription = stream.subscribeToValue { value in }

valueObserver?.next(50)

var secondValues: [CGFloat] = []
let secondSubscription = stream.subscribeToValue { value in
secondValues.append(value)
}

XCTAssertEqual(secondValues, [50])

subscription.unsubscribe()
secondSubscription.unsubscribe()
}

@available(*, deprecated)
func testDeprecatedInitialValueIsReceivedFirst() {
let property = createProperty()

var values: [CGFloat] = []
let subscription = property.initialValue(10).subscribeToValue { value in
values.append(value)
}

property.value = -10

XCTAssertEqual(values, [10, 0, -10])

subscription.unsubscribe()
}
}

0 comments on commit 959ecd2

Please sign in to comment.