iPhone - extend UIImage for custom drawing at runtime - iphone

How can I subclass and draw on an UIImage directly?
I tried extending it and draw on drawAtPoint: or drawInRect: using CoreGraphics, but the image is blank. And neither of the above 2 draw methods are called.
Please don't answer me that I can draw on the UIView because I need a custom runtime designed UIImage.

It's clearly stated in the UIImageView document:
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIImageView_Class/Reference/Reference.html
Subclassing Notes Special Considerations
The UIImageView class is optimized to draw its images to the display.
UIImageView will not call drawRect: a subclass. If your subclass needs
custom drawing code, it is recommended you use UIView as the base
class.
Because telling you to use UIView instead is now allowed, I'll just answer that it's impossible to override drawRect: for UIImageView.

Related

Draw images on CGContext without initWithFrame

I currently have an UIImage object which gets initialized with initWithFrame and then I have some 2D drawings in -(void)drawRect:(CGRect)rect{} with `CGContext. Very basic. All I want to know is, how can I draw through the push of e.g. a button or any event (not only on initialization)?
I tried copying the code inside drawRect to a new method called redraw but this results in an obvious error:
CGContextMoveToPoint: invalid context 0x0
I only want to know how to be able to draw through CGContext while the UIView has been created. Not e.g. how to listen for an UIButton event
Thank you.
You can only draw inside a UIView's drawRect: method or by creating your own image context. You cannot draw to the screen by any means other than drawRect: or implementing drawing for a CALayer. You need to set variables on your view accordingly, then call setNeedsDisplay to have it redrawn. For example, add a property #property(retain) UIImage *image; to your view, set the new image on it and then call setNeedsDisplay (or even better, implement the setImage: method and call [self setNeedsDisplay]; here).

what is the difference between UIImageView and drawInRect?

I want to display so many images in table cells. I knew two methods to show an image.
One is creating an instance to UIImageView and show it
CGRect rect=CGRectMake(x,y,width,height);
UIImageView *image=[[UIImageView alloc]initWithFrame:rect];
[image setImage:[UIImage imageNamed:#"sample.jpg"]];
Another method is,
CGRect rect=CGRectMake(x,y,width,height);
[[UIImage imageNamed:#"sample.jpg"] drawInRect:rect];
Now, my question is, what is the difference between these two? Which one is efficient? Or someother function is available better than this?
Thanks in advance....
Using the drawInRect: method has CoreGraphics draw the image into the active CGContext using the CPU. Assuming you're in a UIView's drawRect: method, this will paint the image into the view's buffer.
UIImageView uses whichever image is assigned to it as it's backing buffer instead of using the slower drawRect:. The GPU then references this buffer directly when the screen is composited via QuartzCore.
UIImageView is a UIView subclass. By adding it to the view hierarchy you get all the free benefits: animations, size properties, affine transoforms, etc. Plus, you are able to change the underlying UIImage any time you want.
On the other hand, calling drawInRect: will just draw the image where you tell it to, but not interact with the UIView hierarchy, so you don't gain any of the benefits from having it on the view hierarchy.
I would think (have not tried it), that drawing the image directly is faster, but I would think in most of the cases having a UIImageView is a better idea.

Drawing a line in a UIView subview

I have a UIView subclass. This subclass has multiple subviews. Is it possible to draw a line using core graphics inside a subview that is part of the uiview subclass?
For example, I have a SampleView class, which is a subclass of UIView. Inside this class's header file is the property for UIView *sampleSubView, which is a subview of SampleView. Is it possible to draw a line inside of sampleSubView from the SampleView class implementation?
Thanks for your help!
Josh
If you are asking how a UIView subclass can draw a line on itself, then see the Quartz demo sample code. Basically, you'll override the view's drawRect: method, get the current graphics context, then draw whatever you like onto it.
If you are asking how one view can draw a line on another view, perhaps you need to rethink your architecture.

Draw graphics inside a UIButton

I have some (fairly large) UIButtons. Instead of text, I would like to draw some simple colored graphics inside them (lines, boxes).
How can it be done without resorting to using prerendered images?
As you cannot subclass UIButton, you should subclass UIView and implement the drawRect: method. Then, add this to your UIButton as a subview.

How can I blend between my UIView and my EAGLView?

I have an opengl scene rendering on an EAGLView layer and some other elements (circles and such) rendering on a UIView (which is a sibling of the EAGLView, positioned above it). Is it possible to blend colors between the two layers? I'd like to do some difference blending to get an inversion effect on the colors from EAGLView.
I've been playing around with CGBlendMode but it only seems to affect what I'm drawing in that current view. I think this has something to do with the CGContext but I'm a little hazy on the details, can I force the UIView and the EAGLView to have the same CGContext so that the blending works between them?
Help, corrections, clarifications are all appreciated. Thanks in advance,
-S
Short answer is you can not. Long answer follows.
By EAGLView you must mean the subclass of UIView that is included in the OpenGL ES Template in Xcode. What makes this class special is that the layerClass class method is overridden and return the CAEAGLLayer class instead of the CALayer class, as is default.
UIView and CALayer work in pairs. All UIView objects are backed by a CALayer, the CALayer is the object responsible for layout and rendering to screen. The UIView is a delegate to the CALayer, and is responsible for drawing it's graphics when needed.
CALayer will let it's delegate (the UIView) draw into a CGContextRef. It is one context per UIView, so you can not use CGBlendMode to blend several views since it will only function within one single UIView context.
Blending of CALayer should be done using the filter properties. These are defined for iPhone OS but the available filters are undefined according to the documentation. This is because Core Image is not available on iPhone OS at this time.
I don't think you'll be able to blend colours in that sense. The best you can do is have one completely obscuring the other, or have the top layer semi-transparent (in which case, you'll see the part underneath) - but you won't be able to do XOR type drawing.