by Chadwick Wood
March 25th, 2010
I recently needed to create one of those magnifying glasses in an iPhone app that shows you a close-up view of where you're touching. Searching around led me to this article by Sean Christmann, which was really helpful in showing me how to create what I was looking for (Thanks Sean!).
However, once I got familiar with his approach, it seemed like there had to be a simpler and possibly more efficent way to get the same thing. He generates a cached image to get the effect, which takes up some memory, but more importantly, it also prevents the magnifying glass from having live updates (which I needed). In other words, once the magnifier is there, any activity going on beneath it won't be properly shown.
So, I wrote my own. Whereas Sean's magnifier generates an image, does some transforms on it, then shows a masked portion of that static image, mine does some transforms on the context of the magnifier view itself, then renders the view to be magnified directly into the magnifier view. Thus, every time the magnifier is re-drawn, it is rendering the current state of the view, resulting in live updates. Here's the drawRect method for my version of the magnifier:
- (void)drawRect:(CGRect)rect {
// here we're just doing some transforms on the view we're magnifying,
// and rendering that view directly into this view,
// rather than the previous method of copying an image.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context,1*(self.frame.size.width*0.5),1*(self.frame.size.height*0.5));
CGContextScaleCTM(context, 1.5, 1.5);
CGContextTranslateCTM(context,-1*(touchPoint.x),-1*(touchPoint.y));
[self.viewToMagnify.layer renderInContext:context];
}
In my typical fashion, I'm going to leave out a lot of the other details about how my implementation differs, but I'll be happy to answer any questions in the comments.
Here's a zip of the XCode project containing my Magnifier.
Also, if you'd like to know when I post more article like this, join the Coffeeshopped Newsletter.