2010-01-08 15 views
19

Me gustaría poder crear una lupa móvil (como la que tiene al copiar y pegar) en una vista personalizada, para ampliar una parte de mi vista.iPhone, reproduzca el efecto de lupa

No tengo idea de cómo empezar, ¿tienes alguna idea?

Gracias de antemano por su ayuda :)

+0

Interesante pregunta. Sin embargo, no tengo ideas. –

Respuesta

16

Hacemos esto en los crucigramas. En su método drawRect, enmascare un círculo (utilizando un mapa de bits monocromático que contenga la "máscara" de su lupa) y dibuje su vista de sujeto con una transformación de escala 2x. Luego dibuja una imagen de lupa sobre eso y listo.

- (void) drawRect: (CGRect) rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGRect   bounds = self.bounds; 
    CGImageRef  mask = [UIImage imageNamed: @"loupeMask"].CGImage; 
    UIImage   *glass = [UIImage imageNamed: @"loupeImage"]; 

    CGContextSaveGState(context); 
    CGContextClipToMask(context, bounds, mask); 
    CGContextFillRect(context, bounds); 
    CGContextScaleCTM(context, 2.0, 2.0); 

    //draw your subject view here 

    CGContextRestoreGState(context); 

    [glass drawInRect: bounds]; 
} 
+0

Suena realmente interesante. Solo necesitaré agregar una superposición para tratar de imitar el reflejo. Voy a probarlo. ¡Muchas gracias! –

+0

Funciona bien. Gracias –

+0

¡El código no admite una sombra en el área sin escalar! ¿Cómo arreglar esto? – Dmitry

4

Hay un ejemplo completo over here. Hay un error menor en el proyecto descargado, pero de lo contrario funciona muy bien y hace exactamente lo que necesita.

+0

+1 para compartir el enlace – Cyprian

+0

¿Se pueden extraer los bits relevantes en la respuesta? Parece que el enlace todavía funciona, pero no hay garantía de cuánto tiempo permanecerá así. –

1

utilizo este código en Swift 3:

class MagnifyingGlassView: UIView { 

    var zoom: CGFloat = 2 { 
     didSet { 
      setNeedsDisplay() 
     } 
    } 

    weak var readView: UIView? 

    // MARK: - UIVIew 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setupView() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setupView() 
    } 

    override func draw(_ rect: CGRect) { 
     guard let readView = readView else { return } 
     let magnifiedBounds = magnifyBounds(of: readView, zoom: zoom) 
     readView.drawHierarchy(in: magnifiedBounds, afterScreenUpdates: false) 
    } 

    // MARK: - Private 

    private func setupView() { 
     isOpaque = false 
     backgroundColor = UIColor.clear 
    } 

    private func magnifyBounds(of view: UIView, zoom: CGFloat) -> CGRect { 
     let transform = CGAffineTransform(scaleX: zoom, y: zoom) 
     var bounds = view.bounds.applying(transform) 
     bounds.center = view.bounds.center 
     return view.convert(bounds, to: self) 
    } 
} 

extension CGRect { 
    var center: CGPoint { 
     get { 
      return CGPoint(x: origin.x + width/2, y: origin.y + height/2) 
     } 
     set { 
      origin.x = newValue.x - width/2 
      origin.y = newValue.y - height/2 
     } 
    } 
} 

es necesario llamar a setNeedsDisplay en scrollViewDidScroll: si su vista de lectura es un ScrollView.

Cuestiones relacionadas