Being playing with SVGKit, I more or less find my way around, using code like this:
CALayer *layer;
layer=[svgView.document layerWithIdentifier:#"path1730"];
But this is when I know the identifier of the layer I want to look at.
Is there a way for me to get a list of all the identifiers (layers) in the document?
You would reference svgView.document.layerTree, which is the root of the sublayers. You'll need to recursively descend through the sublayers to catch all of them. Alternately, if you're working from a single SVGPathView, you can use its enumerateChildLayersUsingBlock: method and pass it a block that will operate on each sublayer in the view.
Related
For this project, I'm using the addCurve method of CGMutablePath to draw a curve-shape on a view.
What I'm not understanding at all, is how (or whether it's even possible) to remove that exact same curve from the mutable path? Judging by the API, it looks like there are lots of methods for adding various shapes at different points, but no methods on how to remove them...
Is not possible, you may hold the elements of the original path so you can construct a new one just with the elements you want or, you can use CGPath.applyWithBlock to construct a new one selecting the wanted elements.
I am working on a prototype for building a DFD builder. This will have a palette of different objects for drawing DFD. (Rectangle boxes, arrows, Ellipses,circles).
I initially planned to use plain CAShapeLayer's to create objects and add it to the superview's layer (with help of CGPaths or UIBezierPath), so that I will reduce the memory footprint of the application.
Then I realized that using CAShapeLayer and adding them directly in super view's layer makes me to handle touches and use hit test to find the CAShapeLayer that was interacted by the user.
So I am planning to create a Custom UIView backed by CAShapeLayer so that I do not bother about handling the touches and spotting the specific object interacted by user.
Is this approach better than using plain CAShapeLayer? and if yes, please provide the reasons?
UPDATE:
#matt I did a memory testing and the results show that using CAShapeLayer will save memory
Neither approach is "better". A layer cannot exist without a view, and you can hit-test a layer just as well as you can hit-test a view. If you have multiple tappable drawn objects then it is going to be simplest if they are all separate layers so that you don't have to calculate which one was tapped; but that does not mean that they all need to be separate views.
As for "memory footprint", you are optimizing prematurely, a cardinal sin. Have you actual evidence that 100 layers (let's say) takes up less "memory footprint" than 100 views? Unless you do, you can't use that as a decision criterion.
I've got a CAShapeLayer and was trying to draw it by passing it to CGContextDrawLayerAtPoint but get an error about passing a retainable parameter of CAShapeLayer *__strong to a function expecting a CGLayerRef.
I've done some browsing but can't figure out how to convert it/bridge the CAShapeLayer to the CGLayerRef.
If its not possible to convert, then can a CAShapeLayer be created using CGLayerCreateWithContext?
What I'm doing is creating a drawing with a UIBezierPath, then creating a CAShapeLayer and setting its path to the UIBezierPath then I want to display it. I could use addSublayer to display the shape layer however I'm going to display the same shape at multiple different points so rather than add multiple sublayers I was planning on using CGContextDrawLayerAtPoint to display it at different points.
Short answer: no.
Long answer: CAShapeLayer is a Core Animation layer (CALayer). You put it into your interface and it draws itself.
I know it's confusing, the way they use the word "layer", but CGContextDrawLayerAtPoint has nothing to do with that (it's using the word "layer" in a totally different way, referring to a CGLayer, which is completely different and is used utterly differently). You've gone down the wrong rabbit hole here.
I could use addSublayer: to display the shape layer
Not could. Must. That is what you do with a CAShapeLayer.
The alternative you are looking for would be to pull the CGPath out of the CAShapeLayer and assign that path and stroke it, multiple times in multiple places, in a CGContext. But there is really no need to do that. iOS drawing is all about layers; don't be afraid of having multiple sublayers.
So I'm looking into UIKit Dynamics and the one problem I have run into is if I want to create a UIView with a custom drawRect: (for instance let's say I want to draw a triangle), there seems to be no way to specify the path of the UIView (or rather the UIDynamicItem) to be used for a UICollisionBehavior.
My goal really is to have polygons on the screen that collide with one another exactly how one would expect.
I came up with a solution of stitching multiple views together but this seems like overkill for what I want.
Is there some easy way to do this, or do I really have to stitch views together?
Dan
Watch the WWDC 2013 videos on this topic. They are very clear: for the sake of efficiency and speed, only the (rectangular) bounds of the view matter during collisions.
EDIT In iOS 9, a dynamic item can have a customized collision boundary. You can have a rectangle dictated by the frame, an ellipse dictated by the frame, or a custom shape — a convex counterclockwise simple closed UIBezierPath. The relevant properties, collisionBoundsType and (for a custom shape) collisionBoundingPath, are read-only, so you will have to subclass in order to set them.
If you really want to collide polygons, you might consider SpriteKit and its physics engine (it seems to share a lot in common with UIDynamics). It can mix with UIKit, although maybe not as smoothly as you'd like.
One of the things sorely lacking from iOS is the ability to set keys on an attribute/attributes and interpolate between them using a spline. Has anyone thought about this and/or found an approach to get around this? Is everyone using Cocos2d for this sort of thing? Cocos2d is way more capability then I need?
Thanks,
Doug
Check out the CAKeyframeAnimation class. UIViews use Core Animation layers, so a Core Animation...er...animation that you apply to a view’s layer gets applied to its contents as well. Most appearance-related properties on CALayer are animatable—obvious ones like frame and opacity, for instance, but also things like backgroundColor and cornerRadius.