Combining drawRect: with other UIKit drawing - uikit

I'm working on some other person's code, which does most of the UI drawing in drawRect:. However, I need to add some animations (UIActivityIndicator animating, for example) to the view, and since drawRect: appears to be frame based, there doesn't seem to be an easy way.
I understand it is a mistake to fiddle with view hierarchies in drawRect, so I can't simply addSubview:. I want the activity indicator to do its own drawing, after drawRect:, because it should overlap. How should I approach this?

Related

Improve CGContextDrawImage performance

I have a custom NSView that has it's own drawRect. I draw a lot of images using CGContextDrawImage into the view. The NsView is in a NSScrollView. The issue I am having is, while scrolling, the drawrect takes too long. the scrolling isn't smooth.
I did try setting wantslayer to true, to enable layer-backed drawing. Now the scrolling is smooth until the next drawrect is called, i.e till next time a new dirtyRect has to be redrawn.
Since I have to use drawrect to draw the contents, is there a way to improve scrolling performance?
if not, is there an alternative?
Update:
the call that's taking time.
I tried what Rob suggested below (using NSImageView for each image). that helped. I see smooth scrolling while setting the images as well.
But I would like to know why CGContextDrawImage takes time? especially rgbaf16_sample_rgbaf_inner. is there a way to avoid it?

How to animate horizontal bar with right cap, by UIView animation in iPhone

I got wiered but unsurprising animation from call UIView animation, I don't know if it works the same by using CALayer animation. I guess it is.
please see this picture: what I want is to animate a horizontal bar growing horizontally, what I do is:
Subclass a UIView, called UIViewBar, and in its drawRect:rect method, I draw the shape of rectangle and a right cap, it's done by
CGContextMoveToPoint A
CGcontextAddLineToPoint B
CGContextAddArcToPoint D
CGContextAddLineToPoint C
//then close the path and fill the context
Then I call this UIViewBar (initWithFrame:rect) in my UIViewController, and the shape is what I want, looks fine. BUT when I perform [UIView animation] say from original rect to rectGrew it does not perform nicely. Instead, it perform as the picture says.
Well, after thinking, it's not totally unreasonable because when the UIView horizontally stretches itself, it does not know the cap will not be changed. So is there another way to do this?
Actually, I'm very new to drawing, graphic, and animation. What I know is that (if wrong please kindly correct me):
If I want to "draw something", I should override the UIView's drawRect method, and this is done by initing the UIView, should not or better not to be called outside. Say I drew a rectangle in a UIView by CGContextFillRect.....
But what if I want to animate this rectangle? I cannot make animation based on Quartz2D, but from UIView animation or CALayer(deeper tech), so What I have to do is to make the rectangle itself as a seperate UIViewRect seperately, so I can call the [UIViewRect animation] method, AM I RIGHT ON THIS
If so, I have to make every rectangle that I want to animate to be UIView respectively. Doesn't it affect performance? Or it is just the way apple prefers to do ?
Any suggestion will be much helpful, GREAT thanks.
Wow, it's the first time that no answer posted at all! TO answer my question: it requires to consider animate custom property of CALayer. The custom property is the AB width (the width without cap width, that should work). If someone wants detailed code. Please google custom property animate in CALayer.

drawRect makes scrolling slow in UIScrollView

I've got a UIScrollView with a (custom) UIView inside of it.
In my scrollViewDidScroll-method I'm calling
[myCustomView setNeedsDisplay];
This makes the scrolling noticeably slower, if I'm implementing the drawRect: method in my custom UIView - even if it's completely empty.
As soon as I delete the drawRect: method, it's smooth again.
I have absolutely no idea, why... anyone of you?
I hate drawrect too
"It's because of the way hardware-accellerated animation works in Cocoa.
If you don't have a custom drawRect method, the system caches the pixels for your view in video memory. When it needs to redraw them, it just blits the pixels onto the screen.
If you have a custom drawRect method, the system instead has to call your drawRect method to render the pixels in main memory, then copy those pixels into video memory, THEN draw the pixels to the screen for each an every frame. The docs say to avoid drawRect if you can.
I think main memory and video memory are shared on most/all iOS devices, but the system still has a lot more work to do when you implement a drawRect method for a view.
You would probably be better served to use an OpenGL layer and render to that with OpenGL calls, since OpenGL talks directly with the display hardware."
link to that quote: http://www.iphonedevsdk.com/forum/iphone-sdk-development/80637-drawrect-makes-scrolling-slow-uiscrollview.html

CATiledLayer to draw giant UIView with buttons?

I've got this giant UIView with around 600 UIButtons as subviews. The UIView is about 2000 by 2000 pixels and it's a subview on itself for a UIScrollView. I'm trying to implement CATiledLayer as the rendering layer for this giant UIView but I can't seem to figure out how to render the tiles. I found a lot of examples that cover CATiledLayer with tiled images, pdf's, ... but I never found a real example on how to draw a complete UIView with a lot of subviews. You're probably asking why i'd like to stick with UIView? Because I'd like the users to keep on using the buttons to interact with the view.
I'm wondering if someone has an example or some psuedo code on how to implement the - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context method, keeping in mind that there's 1 giant UIView with a lot of UIbuttons as its subviews.
Starting with iOS 4.0, you can use drawRect: instead of drawLayer:inContext:. This Q&A from Apple explains it: http://developer.apple.com/library/ios/#qa/qa1637/_index.html. The important point from it is that drawRect: in 4 is now thread-safe and you can use UIKit graphics functionality.
You still need to override this method to use a CATileLayer:
+(Class)layerClass
{
return [CATiledLayer class];
}
But you can now just use drawRect:
-(void)drawRect:(CGRect)rect
{
//normal drawing routines here.
}
The rect that is delivered to the method will be the size of your tiles and you need to determine what needs to be drawn in the particular rect. The power of CATiledLayer is that it only calls for drawing the tiles that are showing on the screen. It also uses background threads and is very fast.
I have not used CATiledLayer with UIViews, only large images. Are the UIViews subclasses with their own drawRect: implementations? I think you will need to determine which views will be showing in the current rect and call their drawRect: method.
Using drawRect: is only for iOS 4.0 and later, it won't work for older versions.

How to Rotate a CALayer-backed NSView subclass

I have a custom NSView subclass that I want to animate with Core Animation. I am already (without CA) setting the position and rotation of these views with NSView's setFrameOrigin and setFrameRotation methods. However, no matter what I do, once I add a layer backing to the views I can't get them to rotate.
I've tried using NSView's setFrameRotation and setFrameCenterRotation methods. The latter moves the view a bit, but doesn't rotate its content. The former has no effect. Applying a CATransform3D created by CATransform3DRotate to the view's layer also has no effect.
I'm feeling a little dumb asking this question, because it seems like something that should be easy, but for the life of me I can't figure out how to make it work. Someone, please make me smack my forehead at how easy it was. :)
Turns out that the superview needed to be layer-backed as well in order for this to work. Making that change fixed it.

Resources