Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a magnifier to custom control?

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?

like image 662
Dmitry Avatar asked Nov 11 '12 12:11

Dmitry


People also ask

Where is my Magnifier?

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.

How do I use the Magnifier on my computer?

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.

How do I change the Magnifier in Windows 10?

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.


1 Answers

1. Add the following files to your project:

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

2. Add the following images:

Used images on the code:

[email protected]:

loupe-hi@2x.png

[email protected]:

loupe-mask@2x.png

Original but centered images with a shadow (not used at this moment):

[email protected]:

loupe-shadow-hi@2x.png

[email protected]:

loupe-shadow-mask@2x.png

3. Replace the main UIView on your xib-file by TouchReader

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];
like image 186
Dmitry Avatar answered Nov 02 '22 04:11

Dmitry