is there MouseChildren for CALayer hit test? - iphone

Hey.
i have a main layer that contains a 4 circle layers and inside each circle there is a text layer :
main layer -> (4)circle layer -> (1)textLayer.
I am performing hit test on the main layer and i want to receive the circle that was clicked.
It works fine, but when I tap in the text area i get back the text layer and not the circle layer.
In AS3 you have
MouseChildren = true/false.
How can i get this functionality in objective c?
thanks
shani

Just use the superlayer property, like this:
if([theLayer isKindOfClass:[CATextLayer class]])
theLayer = theLayer.superlayer;
In other words, if you've already got the circle layer, theLayer doesn't change; if it's one of the text sublayers, theLayer changes to point to the layer that contains that sublayer.

Related

Prevent `CALayer` from dropping shadow set by its parent layer

Recently I've been playing around with shadows and one particular case got me really interested. Suppose I have a parent CALayer which has three oval-shaped sublayers laid in a stack. I applied shadow to the parent layer
containerLayer.shadowColor = UIColor.black.cgColor
containerLayer.shadowRadius = 10
containerLayer.shadowOpacity = 1
and this is the result I got:
But what if I didn't want the green oval to drop shadow? I continued the experiment and set fillColor of the green layer to nil to find out that this in fact does exclude it from combined shadow on the parent layer:
So I got a question: is it possible to both prevent certain layer from dropping a shadow AND preserve layer fillColor or any of that layer's sublayers?
I've tried adding a sublayer to now invisible green oval-shaped layer, but that immediately renders the shadow underneath it. Here's how it looks:
Orange square is a direct sublayer of now invisible green oval.
While this is not really what's happening, you can think of the view's layer casting the shadow.
That's why if we have two sublayers, one with a filled path and one with a stroked path, we get this:
That's also why, if the view's layer or background is not clear, we get this:
So, when we apply a shadow to the "root" layer, it and its sublayers are "flattened" and the shadow is applied to the non-clear portions.
For your example, if you want shadows on the red and blue layers, but not the green layer, you can apply the shadows to the individual sublayers:
You didn't say in your question whether or not you want the blue-layer shadow to appear overlapped on green. If not, there are a couple ways to "move it under"...
First, we can create a duplicate of the blue layer - added first - and give that layer a shadow instead of the "top" blue layer:
A little tough to tell, but we now have 4 sublayers:
Alternatively, we could set the shadow on the red layer, no shadow on green or blue, but then add a .shadowPath to the view's "root" layer:

CAShapeLayer Line drawing

I am drawing line over 5 custom uiviews (Like UITableView rows) from one position to another (X,Y axis) using CAShapeLayer.
My issue is that I want to know that what view the CAShapeLayer (line in my case) is currently in. Is there any CGIntersect for CALayer and CGRect etc? I am trying to create graph using core animation instead of any chart API.
You could check in the shape layer intersects a specific layer by checking intersection of the bounding box of the path agains the frame of the other layer.
BOOL doesIntersect = CGRectIntersectsRect(CGPathGetBoundingBox(path), layer.frame);

How to create round shape UIview instead of rectangle shape

Hi in my application i need a view which is of round shape instead of a rectangle shape. How to create a uiview object of round shape please let me know. Thanks in advance.
Technically, all UIView's will always be "rectangles", meaning they will be placed on the screen using {x, y} coordinates and they will be dimensioned with a height and a width (Making them rectangles). However, within the bounds of a UIView you can do a lot to make it appear as a circle. Here are some methods:
Use UIImageView and set it's Image to be an image of a circle. This is easy, but not very flexible.
Learn Core Graphics (also known as Quartz2D) and draw a circle in the UIView's -drawRect: method. Quartz 2D Programming Guide
Use a CAShapeLayer for the UIView's layers. CAShapeLayer Class Reference
There are certainly other methods but this should be a good start. If you need to detect touches within the circle, you can use either option 2. or 3. and keep a reference to the CGPathRef (or UIBezierPath) and use CGPathContainsPoint to determine if the touch is within the bounds of the circle and act accordingly.
You can set the cornerRadius of the layer of your view.
#import <QuartzCore/QuartzCore.h>
yourView.layer.cornerRadius = 20;

Static and moving shapes in spacemanager

Dear all,
I have an application that uses cocos2d spacemanager with gravity set to a specific value.
If i want to make a shape in the middle of the screen it will fall down to the floor, if i set the gravity to zero all other object will not move as supposed, if i use a second spacemanager and set its gravity to 0 i cant detect collision between objects from different spacemanagers. how can i add a shape that wont fall down in the middle of the screen and detect its collision while other objects behave correctly according to the gravity set.
Also a question is, should i use shapes (Circle, rectangle, ... etc) with spacemanager and if i want to use a ccsprite (image) i should put it in a shape or i can use the sprite alone (e.g. a tree is not a rectangle or circle collision and reflection wont be natural how can i do this).
regards
Every shape has a property called mass. If you want a shape to be static and respond to collisions just set mass to STATIC_MASS like this:
cpShape *ball = [smgr addCircleAt:cpv(440,70) mass:STATIC_MASS radius:10];
to ad an image, do that:
cpShape *ball = [smgr addCircleAt:cpv(440, 70) mass:STATIC_MASS radius:10];
[super initWithShape:playerShape file:#"ball.png"];
If this doesn't work, set up a cpCCSprite in it with a shape.
You can search for cpCCSprite on google, im sure you'l find something :)

Animation in quartz 2D

I want to create an app which after each 1 second will show 4-5 words on screen but the last word will zoom out/in. I can easily create static words and for the last animating word i need to draw the static again n again.
How can i create 2 separate layers so the static text is on one layer ( i will fill it after each second) and the last word (animated one) will be on other layer.
How to create 2 separate layers? Attached on same screen but handling their drawRect method separately?
If I have understood your query then you should make your own class which will be subclass of UIView and override drawRect method in the implementation, then create 2 objects of your custom UIView class at the place where you are making layer's object. you can have x,y co-ordinate variables which will work separately for both layers....