Calling drawRect to draw on top of CALayer? - ios

I current have a view with its CALayer as an AVCapturePreviewLayer, to output video from the iphone's camera. I would like to call drawRect and draw on top of this video output, like draw a simple line on the screen with the current camera capture in the background. The problem is that everything in drawRect appears behind the AVCapturePreviewLayer instead of in front of it. Is there a way to implement this functionality? Preferably without using multiple views?

Add a sublayer to the view's layer:
[view.layer addSublayer:...];
Then draw what you want on the sublayer.

Related

Setting the image of a UITableViewCell to a circle of a specific color

On my table view, I want to display small circles of certain colors that will provide context for the information. The circles should be in the location that the image would usually be in (the left hand side). Is there an easy way to do this? I was thinking that I could create a new image view and simply draw on it using some drawing routines. The problem is I don't know any of these drawing routines, or at least I don't know how to use them outside of a drawRect function.
Well, the easiest way would be to include the different images in your bundle and conditionally set them to the cell's imageView's image property in cellForRowAtIndexPath:.
However, if you're looking for alternative's you could subclass UITableViewCell, and use CAShapeLayers to draw them programmatically and add them to the cells layer in what ever position you want.
Here's an example of how to use CAShapeLayer to draw a circle:
iPhone Core Animation - Drawing a Circle

How to use a UIView with a CCLayer cocos2d?

I am playing a short video with CCVideoPlayer in cocos2d and at the end of it I am capturing the very last frame of the video and I am showing it on the screen using a UIView because trying to draw it on a CCLayer makes the image show up with slightly different colors. I would imagine that is because the way that things are drawn in cocos2d is different than the way they are drawn on a UIView. So I need some way to keep the image on the screen Using the UIView, and I need to be able to draw sprites etc... on top of this view. So my question is, Is there a way to make a CCLayer transparent so that the UIView containing the image can still be seen and then draw on top of the image using a CCLayer?
(P.S I am using cocos2d v1.1.0-beta2b)

Is content drawn by drawRect able to animate using UIView animation?

On iOS, if there are two circles, both of which are UIView objects, then their center or frame can animate using UIView animation.
But the difficulty is, the container UITreeView containing these two circles, draw a line connecting the centers of the circles, using drawRect. In drawRect, I could use CG or UIKit to draw the line, and I chose to use UIBezierPath's moveToPoint and addLineToPoint to draw the line, which should actually just be CG calls underneath, but easier to use.
But when one circle animates to the other position, the line won't animate with it, so the animation can look kind of weird. Is there a way to make it animate?
I tried animating in the TreeView class instead of inside the UINodeView class (the circle), but that won't help. In fact, if I draw the circle using a random color in its drawRect method, when the circle moves slowly in the animation, the color won't change rapidly, suggesting that its drawRect isn't called. It probably is just CALayer that hold a cached image being animated.
So is there a way to make the line animate as well?
The other methods I can think of is:
1) Use a hack to use a UIView to hold the line also, so its frame can animate, but what if the circle moves so that the line needs to be drawn inside the UIView from (0, 0) to (200, 200), but now the line needs to slant the other way, drawing from (200, 0) to (0, 200), so in this case, it probably won't work. (But if I use some kind of transform to flip the image at the same time, it probably will work, but it seems complicated to consider when the transform should be used)
2) use CADisplayLink to do the animation, and just let it call [treeView setNeedsDisplay]; and in this case, the drawRect will be called for sure. (it can be an overkill, and since the whole background of the TreeView will be first erased, there might be a little flashing on the screen going on)
Or is there a simpler or better way?
You could assign your path to a CAShapeLayer (such as wrapping it in a UIView subclass that returns CAShapeLayer as its +layerClass). The path is assigned to the CGPath -path property (and note that UIBezierPath provides a CGPath property).
Then you have a line in a view that you can animate (such as a group animation using UIView +beginAnimations
.

On iPhone and iPad, can we draw anything without using drawRect?

It seems that the standard way to draw dots, lines, circles, and Bezier paths is to draw them in inside of drawRect. We don't directly call drawRect, but just let iOS call it and we can use [self setNeedsDisplay] to tell iOS to try to call drawRect when it can...
It also seems that we cannot rely on
[self setClearsContextBeforeDrawing: NO];
to not clear the background of the view before calling drawRect. Some details are in this question: UIView: how to do non-destructive drawing?
How about directly drawing on the screen -- without putting those code in drawRect. For example, in ViewController.m, have some code that directly draw dots, lines, circles on the screen. Is that possible?
Without having to drop into OpenGL, the closest you can do to get around the erasure is to convert the context as an image using something like CGBitmapContextCreateImage. From there, you can retain the image in memory (or write it to disk if necessary), and then when you redraw the view, you first draw this original image into the context and then overlay it with new content.

Shape animation in iOS

I have an UIView in which I draw many shapes. I just want to keep redrawing this view in order to make kind of an animation. I searched for animation options, but all animations looks like they only work with properties, like transform, alpha... I just want a timed animation option, and that do not block the screen, I mean, that allows the application to realize the screen was tapped. Is it possible?
It is totally possible and you have a few different ways that you can go about doing it. If you want a simple png sequence style animation you can just fill a UIImageView like this:
imageView.animationImages = myImages;
imageView.animationDuration = 3;
[imageView startAnimating];
or you can override the drawrect function in a custom UIView, set up an NSTimer to tick however frequently you want to change the animation and call setNeedsDisplay on the view to draw the next frame.
Assuming you have a bezier path that represents each shape, try looking at CAShapeLayer - this can be used to draw a path on the screen, and you can animate the position, fill colour and many other properties of it.
Have one CAShapeLayer per shape, and add them as sub layers to your main view's layer.
You need to add the QuartzCore framework to use it, but it is very straightforward and there are plenty of tutorials out there.

Resources