2

I have this idea of transforming a straight line into a circle but the offset of a cell drag in a table view.

As I drag the cell, I want the line to curve into a circle around an image. I've included a picture below to help demonstrate different states with different drag offsets.

Im not sure where to start, was thinking of maybe using UIBezierPath to draw but not sure if that's the best solution.

enter image description here

NSDavidObject
  • 328
  • 2
  • 5
  • 13
  • I haven't tried this out, but after doing some googling I found this, and it may help. Possibly you could create a square and then change the corner radius, increasing it as the cell is dragged out. http://stackoverflow.com/questions/19142759/ios-7-round-framed-button – RMK-Jacob Oct 21 '14 at 00:29
  • Thanks @RMK-Jacob for your prompt comment! Unfortunately,round corners would only change the corners of your view, which can translate a rectangle view into a circle. However it can not transform a line into a circle if that makes any sense. It'd be the same line that narrows down from the corners if using cornerRadius. Thanks again though! :) – NSDavidObject Oct 21 '14 at 16:50

1 Answers1

3

If you want it to animate then you have your work cut out for you.

Core Animation of curves is based on CGPath objects, which is the underlying Core Foundation class behind UIBezierPath.

The secret to making a curve animate from one shape to another is to use the same number and type of control points. You won't be able to use any of the standard arc or oval shortcuts (which generate more complex bezier curves that look like arcs.)

Instead, you'll have to build an approximation of a circle piecewise out of a linked series of cubic bezier curves. You should be able to get fairly close with 4 linked cubic bezier curves who's endpoints line are at the N/S/E/W compass points of a circle, and the intermediate control points are spaced evenly outside the circle. A couple of years ago I looked up an article on the net for approximating a circle using Bezier points. I would suggest doing some searching on that.

Alternately, I guess you could generate a circle bezier curve using one of the CGPath or UIBezier shortcuts, then deconstruct the resulting path into the primitives that make it up. Erica Sadun's outstanding iOS Developer's Cookbook series includes a recipe that shows how to deconstruct a UIBezier path into it's primitives.

Once you have a set of control points for a circle, you would need to re-map them into control points that make your line. (A Bezier curve always passes through it's beginning and end points, and if you put the inner 2 control points of a Cubic Bezier on a line, it will turn the curve into a line.)

Now you have 2 shapes made up of the same number of bezier curves and the same number of control points: A circle and a line. You can transform the line into the circle or the circle into the line by moving each of the control points to different x/y coordinates.

Then you might be able to apply a linear interpolation between the starting and ending coordinates of your control points. Use the user's drag of the table view to generate a value from 0 to 1, and apply that to your interpolated control point values (at 0.0, your control points would be at their "straight line" position and your curve would draw as a straight line. At 1.0, they'd be at their circle position, and your curve would draw as a circle. At points between, they'd be a fraction of the way between their beginning and ending positions, and you'd get a shape that was between a line and a circle.

Once you have figured out how to generate the control points to create a curve that moves smoothly from a straight line to a circle, you are ready to tackle doing it using Core Animation and a CAShapeLayer.

If that makes sense then you can probably figure out how to do this. If you have no idea what I am talking about they you are probably in over your head.

(I'm a senior Cocoa/iOS developer. I've done a lot of Core Animation and it would probably take me 3 or 4 hours to get what you are after to work, once I had the circle bezier control points to start from.)

Come to think of it, it would probably be a lot simpler to use UIView keyframe animation. That lets you specify an array of control points that ALL lie on the desired curve, and generates a smooth curve from those points.. Best yet, it is a UIView animation, which is a heck of a lot easier to use than CAAnimation.

Take a look at my demo project RandomBlobs on github. That should give you a head start on using UIView keyframe animation. The method you want is called animateKeyframesWithDuration:delay:options:animations:completion:.

The down-side of point-based keyframe animation is that sometimes the curve you get has "kinks" or loops in it that you don't expect or want. You have to avoid sharp bends. In sketching it out, though, I think a line-to-circle transition might work with keyframe view animation.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Thanks Duncan! I was thinking of the same thing with linear interpolation for UIBezier path, was just wondering if there's an easier solution out there that would make it easier which I'm not aware of. I've got it working now, will be add my code later on for those who're looking to do something similar :) – NSDavidObject Oct 21 '14 at 16:33
  • @NSDavidObject - Where you able to do the curve from straight line. It will be helpful if you can share some code snippet – nkp Aug 10 '16 at 09:22
  • @npk Yes, I was able to. I'll try to find the project later on and see if I can share it :) – NSDavidObject Sep 22 '16 at 20:07