Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## MacOSX
.DS_Store

## Build generated
build/
DerivedData
Expand Down
14 changes: 12 additions & 2 deletions Fluent.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/* Begin PBXBuildFile section */
9E449CA51B9BB9CA00855EE1 /* Fluent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E449CA41B9BB9CA00855EE1 /* Fluent.h */; settings = {ATTRIBUTES = (Public, ); }; };
9E449CAD1B9BB9F500855EE1 /* Fluent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E449CAC1B9BB9F500855EE1 /* Fluent.swift */; settings = {ASSET_TAGS = (); }; };
9E449CAD1B9BB9F500855EE1 /* Fluent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E449CAC1B9BB9F500855EE1 /* Fluent.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -94,11 +94,12 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = "Matthew Cheok";
TargetAttributes = {
9E449CA01B9BB9CA00855EE1 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0820;
};
};
};
Expand Down Expand Up @@ -154,8 +155,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
Expand Down Expand Up @@ -202,8 +205,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
Expand All @@ -223,6 +228,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
Expand All @@ -234,6 +240,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
Expand All @@ -245,13 +252,15 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
9E449CAB1B9BB9CA00855EE1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
Expand All @@ -262,6 +271,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.matthewcheok.Fluent;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand Down
2 changes: 1 addition & 1 deletion Fluent.xcodeproj/xcshareddata/xcschemes/Fluent.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
108 changes: 54 additions & 54 deletions Fluent/Fluent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

import UIKit

public class Fluent {
open class Fluent {
public typealias AnimationBlock = () -> Void

private var animations: [AnimationBlock] = []
private let duration: NSTimeInterval
private let velocity: CGFloat
private let damping: CGFloat
private let options: UIViewAnimationOptions
private var next: Fluent?

init(duration: NSTimeInterval, velocity: CGFloat, damping: CGFloat, options: UIViewAnimationOptions) {
fileprivate var animations: [AnimationBlock] = []
fileprivate let duration: TimeInterval
fileprivate let velocity: CGFloat
fileprivate let damping: CGFloat
fileprivate let options: UIViewAnimationOptions
fileprivate var next: Fluent?

init(duration: TimeInterval, velocity: CGFloat, damping: CGFloat, options: UIViewAnimationOptions) {
self.duration = duration
self.velocity = velocity
self.damping = damping
Expand All @@ -30,7 +30,7 @@ public class Fluent {

deinit {

UIView.animateWithDuration(duration, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0, options: options, animations: {
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0, options: options, animations: {
[animations, performAdditionalAnimations] in
for animation in animations {
animation()
Expand All @@ -43,120 +43,120 @@ public class Fluent {
}
}

public class ViewFluent: Fluent {
private let view: UIView
open class ViewFluent: Fluent {
fileprivate let view: UIView

enum AffineTransformType {
case None
case Absolute
case Relative
case none
case absolute
case relative
}
private var transformType: AffineTransformType = .None
private var transformMatrix = CGAffineTransformIdentity
private let transformError = "You cannot mix absolute and relative transforms"
fileprivate var transformType: AffineTransformType = .none
fileprivate var transformMatrix = CGAffineTransform.identity
fileprivate let transformError = "You cannot mix absolute and relative transforms"

init(view: UIView, duration: NSTimeInterval, velocity: CGFloat, damping: CGFloat, options: UIViewAnimationOptions) {
init(view: UIView, duration: TimeInterval, velocity: CGFloat, damping: CGFloat, options: UIViewAnimationOptions) {
self.view = view
super.init(duration: duration, velocity: velocity, damping: damping, options: options)
}

public func scale(factor: CGFloat) -> Self {
precondition(transformType != .Relative, transformError)
transformType = .Absolute
transformMatrix = CGAffineTransformScale(transformMatrix, factor, factor)
open func scale(_ factor: CGFloat) -> Self {
precondition(transformType != .relative, transformError)
transformType = .absolute
transformMatrix = transformMatrix.scaledBy(x: factor, y: factor)
return self
}

public func translate(x: CGFloat, _ y: CGFloat) -> Self {
precondition(transformType != .Relative, transformError)
transformType = .Absolute
transformMatrix = CGAffineTransformTranslate(transformMatrix, x, y)
open func translate(_ x: CGFloat, _ y: CGFloat) -> Self {
precondition(transformType != .relative, transformError)
transformType = .absolute
transformMatrix = transformMatrix.translatedBy(x: x, y: y)
return self
}

public func rotate(cycles: CGFloat) -> Self {
precondition(transformType != .Relative, transformError)
transformType = .Absolute
transformMatrix = CGAffineTransformRotate(transformMatrix, cycles * 2 * CGFloat(M_PI_2))
open func rotate(_ cycles: CGFloat) -> Self {
precondition(transformType != .relative, transformError)
transformType = .absolute
transformMatrix = transformMatrix.rotated(by: cycles * 2 * CGFloat(M_PI_2))
return self
}

public func scaleBy(factor: CGFloat) -> Self {
precondition(transformType != .Absolute, transformError)
transformType = .Relative
transformMatrix = CGAffineTransformScale(transformMatrix, factor, factor)
open func scaleBy(_ factor: CGFloat) -> Self {
precondition(transformType != .absolute, transformError)
transformType = .relative
transformMatrix = transformMatrix.scaledBy(x: factor, y: factor)
return self
}

public func translateBy(x: CGFloat, _ y: CGFloat) -> Self {
precondition(transformType != .Absolute, transformError)
transformType = .Relative
transformMatrix = CGAffineTransformTranslate(transformMatrix, x, y)
open func translateBy(_ x: CGFloat, _ y: CGFloat) -> Self {
precondition(transformType != .absolute, transformError)
transformType = .relative
transformMatrix = transformMatrix.translatedBy(x: x, y: y)
return self
}

public func rotateBy(cycles: CGFloat) -> Self {
precondition(transformType != .Absolute, transformError)
transformType = .Relative
transformMatrix = CGAffineTransformRotate(transformMatrix, cycles * 2 * CGFloat(M_PI_2))
open func rotateBy(_ cycles: CGFloat) -> Self {
precondition(transformType != .absolute, transformError)
transformType = .relative
transformMatrix = transformMatrix.rotated(by: cycles * 2 * CGFloat(M_PI_2))
return self
}

override func performAdditionalAnimations() {
if transformType == .Absolute {
if transformType == .absolute {
view.transform = transformMatrix
}
else if transformType == .Relative {
view.transform = CGAffineTransformConcat(view.transform, transformMatrix)
else if transformType == .relative {
view.transform = view.transform.concatenating(transformMatrix)
}
}

public func backgroundColor(color: UIColor) -> Self {
open func backgroundColor(_ color: UIColor) -> Self {
animations.append({
[view] in
view.backgroundColor = color
})
return self
}

public func alpha(alpha: CGFloat) -> Self {
open func alpha(_ alpha: CGFloat) -> Self {
animations.append({
[view] in
view.alpha = alpha
})
return self
}

public func frame(frame: CGRect) -> Self {
open func frame(_ frame: CGRect) -> Self {
animations.append({
[view] in
view.frame = frame
})
return self
}

public func bounds(bounds: CGRect) -> Self {
open func bounds(_ bounds: CGRect) -> Self {
animations.append({
[view] in
view.bounds = bounds
})
return self
}

public func center(center: CGPoint) -> Self {
open func center(_ center: CGPoint) -> Self {
animations.append({
[view] in
view.center = center
})
return self
}

public func custom(animation: AnimationBlock) -> Self {
open func custom(_ animation: @escaping AnimationBlock) -> Self {
animations.append(animation)
return self
}

public func waitThenAnimate(duration: NSTimeInterval, velocity: CGFloat = 0, damping: CGFloat = 1, options: UIViewAnimationOptions = [.AllowUserInteraction, .BeginFromCurrentState]) -> ViewFluent {
open func waitThenAnimate(_ duration: TimeInterval, velocity: CGFloat = 0, damping: CGFloat = 1, options: UIViewAnimationOptions = [.allowUserInteraction, .beginFromCurrentState]) -> ViewFluent {
precondition(next == nil, "You have already specified a completion handler")
let after = ViewFluent(view: view, duration: duration, velocity: velocity, damping: damping, options: options)
next = after
Expand All @@ -165,7 +165,7 @@ public class ViewFluent: Fluent {
}

public extension UIView {
public func animate(duration: NSTimeInterval, velocity: CGFloat = 0, damping: CGFloat = 1, options: UIViewAnimationOptions = [.AllowUserInteraction, .BeginFromCurrentState]) -> ViewFluent {
public func animate(_ duration: TimeInterval, velocity: CGFloat = 0, damping: CGFloat = 1, options: UIViewAnimationOptions = [.allowUserInteraction, .beginFromCurrentState]) -> ViewFluent {
return ViewFluent(view: self, duration: duration, velocity: velocity, damping: damping, options: options)
}
}