How to add a magnifier to custom control? Control is a child of UIView. (It's a UIWebView - but native magnification functionality doesn't work at some pages.)
UPDATED:
Maybe it's possible to force a draw of magnifier on UIWebView?
Some Android phones also have a magnifying glass feature, but you need to turn it on for it to work. To turn on the magnifying glass, go to Settings, then Accessibility, then Vision, then Magnification and turn it on.
To quickly turn on Magnifier, press the Windows logo key + Plus sign (+) . To turn off Magnifier, press the Windows logo key + Esc. If you prefer using a mouse, select Start > Settings > Accessibility > Magnifier, and then turn on the Magnifier switch.
Turn on Magnifier To turn off Magnifier, press the Windows logo key+Esc. If you prefer using a mouse, select Start > Settings > Ease of Access > Magnifier > Turn on Magnifier.
MagnifierView.h:
//
// MagnifierView.h
// SimplerMaskTest
//
#import <UIKit/UIKit.h>
@interface MagnifierView : UIView {
UIView *viewToMagnify;
CGPoint touchPoint;
}
@property (nonatomic, retain) UIView *viewToMagnify;
@property (assign) CGPoint touchPoint;
@end
MagnifierView.m:
//
// MagnifierView.m
// SimplerMaskTest
//
#import "MagnifierView.h"
#import <QuartzCore/QuartzCore.h>
@implementation MagnifierView
@synthesize viewToMagnify;
@dynamic touchPoint;
- (id)initWithFrame:(CGRect)frame {
return [self initWithFrame:frame radius:118];
}
- (id)initWithFrame:(CGRect)frame radius:(int)r {
int radius = r;
if ((self = [super initWithFrame:CGRectMake(0, 0, radius, radius)])) {
//Make the layer circular.
self.layer.cornerRadius = radius / 2;
self.layer.masksToBounds = YES;
}
return self;
}
- (void)setTouchPoint:(CGPoint)pt {
touchPoint = pt;
// whenever touchPoint is set, update the position of the magnifier (to just above what's being magnified)
self.center = CGPointMake(pt.x, pt.y-66);
}
- (CGPoint)getTouchPoint {
return touchPoint;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect bounds = self.bounds;
CGImageRef mask = [UIImage imageNamed: @"[email protected]"].CGImage;
UIImage *glass = [UIImage imageNamed: @"[email protected]"];
CGContextSaveGState(context);
CGContextClipToMask(context, bounds, mask);
CGContextFillRect(context, bounds);
CGContextScaleCTM(context, 1.2, 1.2);
//draw your subject view here
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];
CGContextRestoreGState(context);
[glass drawInRect: bounds];
}
- (void)dealloc {
[viewToMagnify release];
[super dealloc];
}
@end
TouchReader.h:
//
// TouchReader.h
// SimplerMaskTest
//
#import <UIKit/UIKit.h>
#import "MagnifierView.h"
@interface TouchReader : UIView {
NSTimer *touchTimer;
MagnifierView *loop;
}
@property (nonatomic, retain) NSTimer *touchTimer;
- (void)addLoop;
- (void)handleAction:(id)timerObj;
@end
TouchReader.m:
//
// TouchReader.m
// SimplerMaskTest
//
#import "TouchReader.h"
#import "MagnifierView.h"
@implementation TouchReader
@synthesize touchTimer;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.touchTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(addLoop) userInfo:nil repeats:NO];
// just create one loop and re-use it.
if (loop == nil) {
loop = [[MagnifierView alloc] init];
loop.viewToMagnify = self;
}
UITouch *touch = [touches anyObject];
loop.touchPoint = [touch locationInView:self];
[loop setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleAction:touches];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.touchTimer invalidate];
self.touchTimer = nil;
[loop removeFromSuperview];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self.touchTimer invalidate];
self.touchTimer = nil;
[loop removeFromSuperview];
}
- (void)addLoop {
// add the loop to the superview. if we add it to the view it magnifies, it'll magnify itself!
[self.superview addSubview:loop];
// here, we could do some nice animation instead of just adding the subview...
}
- (void)handleAction:(id)timerObj {
NSSet *touches = timerObj;
UITouch *touch = [touches anyObject];
loop.touchPoint = [touch locationInView:self];
[loop setNeedsDisplay];
}
- (void)dealloc {
[loop release];
loop = nil;
[super dealloc];
}
@end
Based on: http://coffeeshopped.com/2010/03/a-simpler-magnifying-glass-loupe-view-for-the-iphone
Used images on the code:
Original but centered images with a shadow (not used at this moment):
The magnifier will work automaticaly except controls that captures touch events themselfs (for example, UIWebView). And the code above doesn't support the images with a shadow. Please add new answer to the qustion if you successfully fix this issue.
UPDATED:
Change the following code to add UIWebView
support. UIView
should remain UIView
.
@interface TouchReader : UILongPressGestureRecognizer
And add a gesture to webView
:
TouchReader* gestureMagnifier = [[[TouchReader alloc] initWithTarget:self action:@selector(handleMagnifier:)] autorelease];
gestureMagnifier.webView = editSource;
gestureMagnifier.delegate = self;
gestureMagnifier.minimumPressDuration = 0.5;
[webView addGestureRecognizer:gestureMagnifier];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With