Ubergang is a tweening engine for iOS written in Swift.
- Tween numeric values, UIColors and CGAffineTransforms
- Tween along UIBezierPaths
- Tween through points
- Linear, Expo, Cubic, Quad, Circ, Quart, Quint, Sine, Back, Bounce and Elastic easings
- Generic tween setup
- Repeat and Yoyo tween options
- Memory management for strong and weak tween object references
- Tween Timelines
- Bezier tween align to path
- Logging and log levels
platform :ios, '8.0'
use_frameworks!
pod 'Ubergang'
UTweenSetup.instance.enableLogging(true)
UTweenSetup.instance.enableLogging(true, withLogger: loggerProxy)
Ubergang provides some logs for basic operations like start, stop, pause, ... There is a dependency to XCGLogger which is used by default, but you can pass any Logger you prefer by creating a custom logger proxy implementing
UTweenLoggable
.
.options(.Repeat(n))
.options(.Yoyo)
.options(.Repeat(n), .Yoyo)
Using
options
you can let the Tween repeat n (Int) times, let it yoyo or combine both options.
- Repeat will restart the Tween n times where
repeatCycleChange
will be called with every cycle. - Yoyo will reverse the Tween after it reaches the end value.
.memoryReference(.Strong)` //(default)
.memoryReference(.Weak)
memoryReference
determines how to handle the reference count for the tween. Ubergang will increase the reference count if the option is set to.Strong
or won't increase it if it's set to.Weak
. These two rules are valid for most cases:
- The Tween is not stored in a field variable ->
.Strong
- The Tween is stored in a field variable ->
.Weak
UTweenBuilder
.to( 10.0, from: 0.0, update: { value in print("test double: \(value)") }, duration: 5, id: "doubleTween")
.start()
This Tween with id 'doubleTween' goes from 0.0 to 10.0 over 5 seconds using a linear easing by default. The current value will be printed with every update.
UTweenBuilder
.to( { [unowned self] in return position1.x }, from: { [unowned self] in return position2.x }, update: { value in print("test double: \(value)") }, duration: 5, id: "doubleTween")
.start()
Passing closures to 'to' and 'from' will always compute all results using the current values returned by the closures.
var tween: NumericTween<Int>?
func run() {
tween = UTweenBuilder
.to( 10, from: 0, update: { value in print("test int: \(value)") }, duration: 5, id: "intTween")
.ease(Elastic.easeOut)
.memoryReference(.Weak)
.start()
}
This Tween with id 'intTween' goes from 0 to 10 over 5 seconds using an elastic easing. The current value will be printed with every update. .memoryReference(.Weak) will store this tween weakly, Ubergang won't increment the reference count. It's up to you to keep the Tween alive.
var tween: NumericTween<Int>?
func run() {
tween = UTweenBuilder
.to( 10, from: 0, update: { value in print("test int: \(value)") }, duration: 5, id: "intTween")
.ease(Elastic.easeOut)
.options(.Repeat(5), .Yoyo)
.memoryReference(.Weak)
.start()
}
@IBOutlet var testView: UIView!
var tween: TransformTween?
func run() {
//declare the target values
var to = testView.transform
to.ty = 200.0
tween = UTweenBuilder
.to( to,
from: { [unowned self] in
return self.testView.transform },
update: { [unowned self] value in
self.testView.transform = value },
duration: 2.5,
id: "testView")
.memoryReference(.Weak)
.start()
}
This Tween with id 'testView' tweens a transform over 2.5 secondsg. The resulting tranform will be assigned to the testView with every update 'welf.testView.transform = value'.
var timeline: UTimeline = UTimeline(id: "timeline")
func run() {
timeline.options(.Yoyo)
timeline.ease(Cubic.easeInOut)
timeline.memoryReference(.Weak)
timeline.append(UTweenBuilder
.to( 10, from: 0, update: { value in print("0-10 value: \(value)") }, duration: 5, id: "intTween")
)
timeline.append(UTweenBuilder
.to( 10.0, from: 0.0, update: { value in print("0.0-10.0 value: \(value)") }, duration: 5, id: "floatTween1")
)
timeline.insert(UTweenBuilder
.to( 0.0, from: 10.0, update: { value in print("10.0-0.0 value: \(value)") }, duration: 5, id: "floatTween2"), at: 2.5
)
timeline.start()
}
This Timeline controls one Tween starting at time 0.0 seconds, one Tween starting at time 5.0 seconds and the last one starting at 2.5 seconds. All Tweens are controlled by the timeline with the given easing and options - In this case the tween option
.Yoyo
with easingCubic.easeInOut
var tween: BezierPathTween!
func run() {
tween = UTweenBuilder
.along( path,
update: { [unowned self] (value:CGPoint, progress: Double) in
//update
},
duration: 5,
id: "bezierTween")
.ease(Linear.ease)
.memoryReference(.Weak)
.start()
}
var tween: BezierPathTween!
func run() {
let points = [CGPoint]()
points.append(...)
tween = UTweenBuilder
.along( points,
update: { [unowned self] (value:CGPoint, progress: Double) in
//update
},
duration: 5,
id: "bezierTween")
.ease(Linear.ease)
.memoryReference(.Weak)
.start()
}
var tween: BezierPathTween!
func run() {
let points = [CGPoint]()
points.append(...)
tween = UTweenBuilder
.along( points,
update: { [unowned self] (value:CGPoint, progress: Double, orientation: CGPoint) in
self.targetView.center = value
let angle = atan2(orientation.y, orientation.x)
let transform = CGAffineTransformRotate(CGAffineTransformIdentity, angle)
self.targetView.transform = transform
},
duration: 5,
id: "bezierTween")
.ease(Linear.ease)
.memoryReference(.Weak)
.start()
}
- Thinking about new features
Feedback is always appreciated