MyNameIsKo
MyNameIsKo

Reputation: 2301

Poor device performance when redrawing views

I'm using NSTimer to refresh 5 contexts and paste them onto 5 views every .03 seconds. This worked fine in the simulator and ran at a great frame rate but then chugs when deployed on an iPod. I dropped the rate down to .1 and saw little improvement. Is there a more efficient way of redrawing these contexts?

Some code:

- (void)addViews{
[self.superview addSubview:mag];
[self.superview addSubview:vc];
[self.superview addSubview:na];
[self.superview addSubview:wave];
[self.superview addSubview:mon];

[self.superview addSubview:selector];

looper = [NSTimer timerWithTimeInterval:0.03
                                target:self
                               selector:@selector(setNeeds)
                               userInfo:nil
                                repeats:YES];

[[NSRunLoop mainRunLoop] addTimer:looper forMode:NSRunLoopCommonModes];
}

-(void)setNeeds{
[mag setNeedsDisplay];
[vc setNeedsDisplay];
[na setNeedsDisplay];
[wave setNeedsDisplay];
[mon setNeedsDisplay];
}

This is the context adjustment applied to each view. Essentially a magnifying glass.

- (void)drawRect:(CGRect)rect {
CGPoint magnifiedPoint = [viewToMagnify convertPoint:coordPoint fromView:self.superview];

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context,(self.frame.size.width*0.5),(self.frame.size.height*0.5));
CGContextScaleCTM(context, 1.3, 1.3);
CGContextTranslateCTM(context,-1*(magnifiedPoint.x),-1*(magnifiedPoint.y));
[self.viewToMagnify.layer renderInContext:context];
}

Upvotes: 0

Views: 759

Answers (1)

Nick Lockwood
Nick Lockwood

Reputation: 41005

Core Graphics drawing is relatively slow because it's not hardware accelerated using OpenGL. For anything but the most trivial drawing, Core Graphics is too slow for real-time animation on iOS.

Core animation is much faster because it uses OpenGL hardware acceleration. I suggest trying to achieve your effect using Core animation as much as possible. Every UIView is backed by a CALayer so any transforms you apply to your view.transform property directly will be very fast. You can also dynamically mask a view using an image by setting the view.layer.mask property.

Perhaps you could simulate your magnification effect by scaling the view itself (or a copy of the view with the same content) and masking it to a circle. That way you wouldn't ever have to call renderInContext or do any CGContext drawing, and the whole thing should run at a decent frame rate.

Upvotes: 1

Related Questions