The iPhone 4 can be much slower when it comes to CoreGraphics processing.
One possible idea for your case. When the user is scrolling, rather than draw full resolution, draw your CoreGraphics related stuff a half resolution context. Then take that context as a bitmap and scale it up to full resolution. This would be for iPhone4 only and you would lose the nice higher resolution quality, but only be while the user is scrolling.
Here's some code I wrote up for testing between the different devices.
My results when displaying the view at full screen.
- 3G, 9 FPS
- 3GS, 16 FPS
- i4, 5 FPS (bummer)
CoreGraphicsTestView.h
#import <UIKit/UIKit.h>
@interface CoreGraphicsTestView : UIView
{
int displayCounter;
float displayInterval;
char fps[50];
}
@end
CoreGraphicsTestView.m
#import "CoreGraphicsTestView.h"
#define RNDN(s, e) ((((CGFloat)rand() / (CGFloat)INT_MAX) * ((e)-(s)) + (s)))
#define RNDX(s, e, r) (RNDN((s), (e)) * (r).size.width)
#define RNDY(s, e, r) (RNDN((s), (e)) * (r).size.height)
#define RNDR(r) (CGRectMake(RNDX(0,0.50,(r)),RNDY(0,0.50,(r)),RNDX(0.50,1.0,(r)),RNDY(0.50,1.0,(r))))
@implementation CoreGraphicsTestView
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
self.backgroundColor = [UIColor blackColor];
srand(time(NULL));
fps[0] = '\0';
}
return self;
}
- (void)updateDisplayCounter:(CGContextRef)c rect:(CGRect)rect
{
displayCounter++;
float now = (float)clock() / (float)CLOCKS_PER_SEC;
if (now - displayInterval > 1)
{
sprintf(fps, "%0.0f", displayCounter / (now - displayInterval));
printf("%s\n", fps);
displayInterval = now;
displayCounter = 0;
}
CGContextTranslateCTM(c, 5, 40);
CGContextScaleCTM(c, 1.0, -1.0);
CGContextSetFillColorWithColor(c, [UIColor whiteColor].CGColor);
CGContextSelectFont(c, "Arial", 18, kCGEncodingMacRoman);
CGContextShowTextAtPoint(c, 0, 0, fps, strlen(fps));
}
- (void)setRandomColor:(CGContextRef)c
{
CGFloat components[4] = {1,RNDN(0, 1),RNDN(0, 1),RNDN(0, 1)};
CGContextSetFillColor(c, components);
}
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
for (int i=0;i<5;i++)
{
[self setRandomColor:c];
CGContextFillRect(c, RNDR(rect));
[self setRandomColor:c];
CGContextFillEllipseInRect(c, RNDR(rect));
}
[self updateDisplayCounter:c rect:rect];
[self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.0];
}
@end