diff --git a/FrictionCurves.xcodeproj/xcuserdata/victorbaro.xcuserdatad/xcschemes/FrictionCurves.xcscheme b/FrictionCurves.xcodeproj/xcuserdata/victorbaro.xcuserdatad/xcschemes/FrictionCurves.xcscheme
index 6b19159..ad8e0b0 100644
--- a/FrictionCurves.xcodeproj/xcuserdata/victorbaro.xcuserdatad/xcschemes/FrictionCurves.xcscheme
+++ b/FrictionCurves.xcodeproj/xcuserdata/victorbaro.xcuserdatad/xcschemes/FrictionCurves.xcscheme
@@ -5,6 +5,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -32,6 +91,16 @@
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
+
+
+
+
diff --git a/FrictionCurves/Base.lproj/Main.storyboard b/FrictionCurves/Base.lproj/Main.storyboard
index 77ba998..f49ed79 100644
--- a/FrictionCurves/Base.lproj/Main.storyboard
+++ b/FrictionCurves/Base.lproj/Main.storyboard
@@ -1,13 +1,14 @@
-
+
-
+
+
-
+
@@ -16,38 +17,109 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -56,31 +128,46 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FrictionCurves/FirstViewController.swift b/FrictionCurves/FirstViewController.swift
index 2bf6792..79318dc 100644
--- a/FrictionCurves/FirstViewController.swift
+++ b/FrictionCurves/FirstViewController.swift
@@ -10,16 +10,78 @@ import UIKit
class FirstViewController: UIViewController {
+ @IBOutlet weak var topViewLeadingConstraint: NSLayoutConstraint!
+ @IBOutlet weak var middleViewLeadingConstraint: NSLayoutConstraint!
+ @IBOutlet weak var bottomLeadingConstraint: NSLayoutConstraint!
+
+ @IBOutlet weak var movingView: UIView!
+ @IBOutlet weak var movingViewLeadingConstraint: NSLayoutConstraint!
+
+ let horizontalLimit : CGFloat = 160.0
+
override func viewDidLoad() {
super.viewDidLoad()
- // Do any additional setup after loading the view, typically from a nib.
+ addVerticalLine()
+
}
+ @IBAction func viewDragged(sender: UIPanGestureRecognizer) {
+ let xPosition = sender.locationInView(view).x
+ movingViewLeadingConstraint.constant = linearConstraintValueForXPoisition(xPosition)
+
+ if (hasExceededVerticalLine(xPosition)) {
+ topViewLeadingConstraint.constant = sqrtConstraintValueForXPoisition(xPosition)
+ middleViewLeadingConstraint.constant = lognConstraintValueForXPoisition(xPosition)
+ bottomLeadingConstraint.constant = powConstraintValueForXPoisition(xPosition)
+
+ if(sender.state == UIGestureRecognizerState.Ended ){
+ movingViewLeadingConstraint.constant = finalConstraintValue()
+ topViewLeadingConstraint.constant = finalConstraintValue()
+ middleViewLeadingConstraint.constant = finalConstraintValue()
+ bottomLeadingConstraint.constant = finalConstraintValue()
+ }
+ } else {
+ topViewLeadingConstraint.constant = linearConstraintValueForXPoisition(xPosition)
+ middleViewLeadingConstraint.constant = linearConstraintValueForXPoisition(xPosition)
+ bottomLeadingConstraint.constant = linearConstraintValueForXPoisition(xPosition)
+ }
- override func didReceiveMemoryWarning() {
- super.didReceiveMemoryWarning()
- // Dispose of any resources that can be recreated.
}
+ func linearConstraintValueForXPoisition(xPosition : CGFloat) -> CGFloat {
+ return xPosition - CGRectGetWidth(movingView.frame)/2
+ }
+ func sqrtConstraintValueForXPoisition(xPosition : CGFloat) -> CGFloat {
+ let linearValue = linearConstraintValueForXPoisition(xPosition)
+ return finalConstraintValue() + sqrt(linearValue - finalConstraintValue())
+ }
+ func powConstraintValueForXPoisition(xPosition : CGFloat) -> CGFloat {
+ let linearValue = linearConstraintValueForXPoisition(xPosition)
+ let powValue = pow(linearValue/finalConstraintValue(), 4.0)
+ return linearValue - powValue
+ }
+ func lognConstraintValueForXPoisition(xPosition : CGFloat) -> CGFloat {
+ let linearValue = linearConstraintValueForXPoisition(xPosition)
+ return finalConstraintValue() * (1 + log10(linearValue/finalConstraintValue()))
+ }
+
+
+//Helping methods
+ func addVerticalLine() {
+ let lineThickness : CGFloat = 2.0;
+ let lineFrame = CGRectMake(horizontalLimit - lineThickness/2, 0, lineThickness, CGRectGetHeight(view.frame))
+ var verticalLineView : UIView = UIView (frame: lineFrame)
+ verticalLineView.backgroundColor = UIColor.redColor()
+ view.addSubview(verticalLineView)
+ }
+
+ func finalConstraintValue() -> CGFloat {
+ let viewWidth = CGRectGetWidth(movingView.frame)
+ return horizontalLimit - viewWidth/2
+ }
+ func hasExceededVerticalLine(xPosition : CGFloat) -> Bool {
+ return xPosition > horizontalLimit
+ }
+
}
diff --git a/FrictionCurves/SecondViewController.swift b/FrictionCurves/SecondViewController.swift
index f417b62..d3c8daa 100644
--- a/FrictionCurves/SecondViewController.swift
+++ b/FrictionCurves/SecondViewController.swift
@@ -10,16 +10,45 @@ import UIKit
class SecondViewController: UIViewController {
+
+ @IBOutlet weak var topViewConstraint: NSLayoutConstraint!
+ let verticalLimit : CGFloat = -200
+ var totalTranslation : CGFloat = -200
+
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
- override func didReceiveMemoryWarning() {
- super.didReceiveMemoryWarning()
- // Dispose of any resources that can be recreated.
+ @IBAction func viewDragged(sender: UIPanGestureRecognizer) {
+ let yTranslation = sender.translationInView(view).y
+
+ if (hasExceededVerticalLimit(topViewConstraint.constant)){
+ totalTranslation += yTranslation
+ topViewConstraint.constant = logConstraintValueForYPoisition(totalTranslation)
+ if(sender.state == UIGestureRecognizerState.Ended ){
+ animateViewBackToLimit()
+ }
+ } else {
+ topViewConstraint.constant += yTranslation
+ }
+ sender.setTranslation(CGPointZero, inView: view)
}
-
+
+ func hasExceededVerticalLimit(yPosition : CGFloat) -> Bool {
+ return yPosition < verticalLimit
+ }
+ func logConstraintValueForYPoisition(yPosition : CGFloat) -> CGFloat {
+ return verticalLimit * (1 + log10(yPosition/verticalLimit))
+ }
+ func animateViewBackToLimit() {
+ self.topViewConstraint.constant = self.verticalLimit
+
+ UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 10, options: UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in
+ self.view.layoutIfNeeded()
+ self.totalTranslation = -200
+ }, completion: nil)
+ }
}