inside example doesn iphone uiscrollview calayer

iphone - example - uiscrollview autolayout



UIScrollView zoomToRect no se acerca al rect dado(creado desde UITouch CGPoint) (8)

Mi aplicación tiene un UIScrollView con una subvista. La subvista es una UIView extendida que imprime una página PDF a sí misma utilizando capas en el evento drawLayer.

Hacer zoom utilizando el pellizco incorporado funciona muy bien. setZoomScale también funciona como se esperaba.

He estado luchando con la función zoomToRect. Encontré un ejemplo en línea que hace una variable zoomRect de CGRect de un CGPoint dado.

En la función touchesEnded, si hubo un doble toque y están completamente alejados, quiero acercarme a esa PDFUIView que creé como si estuvieran pellizcando con el centro del pellizco donde hicieron doble clic.

Así que supongamos que paso la variable UITouch a mi función que utiliza zoomToRect si tocan dos veces.

Empecé con la siguiente función que encontré en el sitio de manzanas:

http://developer.apple.com/iphone/library/documentation/WindowsViews/Conceptual/UIScrollView_pg/ZoomZoom/ZoomZoom.html

La siguiente es una versión modificada para mi clase extendida UIScrollView:

- (void)zoomToCenter:(float)scale withCenter:(CGPoint)center { CGRect zoomRect; zoomRect.size.height = self.frame.size.height / scale; zoomRect.size.width = self.frame.size.width / scale; zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0); zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0); //return zoomRect; [self zoomToRect:zoomRect animated:YES]; }

Cuando hago esto, UIScrollView parece hacer zoom utilizando el borde inferior derecho de la aplicación zoomRect que se muestra arriba y no el centro.

Si hago UIView así

UIView *v = [[UIView alloc] initWithFrame:zoomRect]; [v setBackgroundColor:[UIView redColor]]; [self addSubview:v];

El cuadro rojo aparece con el punto de contacto muerto en el centro.

Tenga en cuenta: Estoy escribiendo esto desde mi PC, recuerdo jugar con el dividido por dos partes en mi Mac, así que asuma que esto dibuja un rect con el punto de contacto en el centro. Si el UIView se desvió del centro pero se amplió al lugar correcto, todo estaría bien.

Sin embargo, lo que sucede es que cuando preforma el zoomToRect, parece utilizar la parte inferior derecha del zoomRect en la parte superior izquierda de los resultados ampliados.

Además, noté que dependiendo de dónde haga clic en UIScrollView, se ancla a diferentes puntos. Casi parece que hay una cruz en el medio y está reflejando los puntos de alguna manera, como si en algún lugar a la izquierda del medio fuera un reflejo negativo y cualquier lugar a la derecha del centro fuera un reflejo positivo.

Esto parece complicado, ¿no debería simplemente acercarse al rect que se dibujó como el UIView fue capaz de dibujar?

Utilicé una gran cantidad de investigación para descubrir cómo crear un PDF que se escala en alta calidad, por lo que estoy asumiendo que el uso de CALayer puede ser arrojado fuera del sistema de coordenadas? Pero para el UIScrollView solo debería tratarlo como una vista con dimensiones de 768x985.

Esto es algo avanzado, asuma que el código para crear el zoomRect está bien. Hay algo más profundo con el CALayer en UIView que se encuentra en UIScrollView ....


En mi caso fue:

zoomRect.origin.x = center.x / self.zoomScale - (zoomRect.size.width / 2.0); zoomRect.origin.y = center.y / self.zoomScale - (zoomRect.size.height / 2.0);


Estoy teniendo el mismo comportamiento y es bastante frustrante ... El rectángulo que se está alimentando al UIScrollView es perfecto ... sin embargo, mi punto de vista, no importa lo que haga cualquier cosa que implique cambiar el zoomScale programáticamente, siempre se amplía y escala para coordinar 0,0 , no importa qué.

He intentado simplemente cambiar el zoomScale, he intentado con zoomToRect, los he probado todos, y cada vez que toco el zoomScale en el código, va a coordinar 0,0.

También tuve que agregar y establecer setContentSize explícito a la imagen redimensionada en la vista de desplazamiento después de una operación de zoom, o de lo contrario no puedo desplazarme después de un zoom o pellizco.

¿Es esto un error en 3.1.3 o qué?


He intentado con diferentes soluciones, pero esta parece ser la mejor resolución. ¿Es realmente directo y conceptual?

CGRect frame = [[UIScreen mainScreen] applicationFrame]; scrollView.contentInset = UIEdgeInsetsMake(frame.size.height/2, frame.size.width/2, frame.size.height/2, frame.size.width/2);


Me he dado cuenta de que la manzana que está utilizando no se acerca correctamente si la imagen está comenzando en un zoomScale menor que 1 porque el origen de zoomRect es incorrecto. Lo edité para que funcione correctamente. Aquí está el código:

- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center { CGRect zoomRect; // the zoom rect is in the content view''s coordinates. // At a zoom scale of 1.0, it would be the size of the imageScrollView''s bounds. // As the zoom scale decreases, so more content is visible, the size of the rect grows. zoomRect.size.height = [self frame].size.height / scale; zoomRect.size.width = [self frame].size.width / scale; // choose an origin so as to get the right center. zoomRect.origin.x = (center.x * (2 - self.minimumZoomScale) - (zoomRect.size.width / 2.0)); zoomRect.origin.y = (center.y * (2 - self.minimumZoomScale) - (zoomRect.size.height / 2.0)); return zoomRect; }

La clave es esta parte que multiplica el valor central por (2 - self.minimumZoomScale). Espero que esto ayude.


No estoy de acuerdo con uno de los comentarios anteriores que dicen que nunca debes multiplicar las coordenadas del centro por algún factor.

Supongamos que actualmente muestra una imagen 400x400px completa o un archivo PDF en una vista de desplazamiento de 100x100 y desea permitir a los usuarios duplicar el tamaño del contenido hasta que sea 1: 1. Si toca dos veces en el punto (75, 75), espera que el rectángulo ampliado tenga origen 100,100 y tamaño 100x100 dentro de la nueva vista de contenido de 200x200. Entonces, el punto de derivación original (75, 75) ahora es (150, 150) en el nuevo espacio de 200x200.

Ahora, después de que la acción de zoom # 1 se haya completado, si vuelve a tocar dos veces (75,75) dentro del nuevo rectángulo de 100x100 (que es el cuadrado inferior derecho del rectángulo más grande de 200x200), espera que el usuario se muestre en la parte inferior -right 100x100 cuadrado de la imagen más grande, que ahora se ampliaría a 400x400 píxeles.

Para calcular el origen de este último rectángulo de 100x100 dentro del rectángulo 400x400 más grande, necesitaría considerar la escala y el offset del contenido actual (ya que antes de esta última acción de zoom mostramos el rectángulo 100x100 de abajo a la derecha dentro de un rectángulo de 200x200) .

Entonces la coordenada x del rectángulo final se convierte en: center.x / currentScale - (scrollView.frame.size.width / 2) + scrollView.contentOffset.x / currentScale = 75 / .5 - 100/2 + 100 / .5 = 150 - 50 + 200 = 300.

En este caso, al ser un cuadrado, el cálculo de la coordenada y es el mismo. Y efectivamente hicimos zoom en el rectángulo 100x100 de la esquina inferior derecha, que, en la vista de contenido 400x400 más grande tiene origen 300,300.

Así es como calcularía el tamaño y el origen del rectángulo del zoom: zoomRect.size.height = mScrollView.frame.size.height / scale; zoomRect.size.width = mScrollView.frame.size.width / scale;

zoomRect.origin.x = center.x/currentScale - (mScrollView.frame.size.width/2) + mScrollView.contentOffset.x/currentScale; zoomRect.origin.y = center.y/currentScale - (mScrollView.frame.size.height/2) + mScrollView.contentOffset.y/currentScale;

Espero que esto tenga sentido; es difícil explicarlo por escrito sin esbozar los diversos cuadrados / rectángulos.

Saludos, Raf Colasante


Ok otra respuesta:

Las rutinas suministradas por Apple funcionan para mí, pero es necesario que el reconocedor de gestos convierta el punto de derivación en coords de imageView, no en el scroller.

El ejemplo de Apple hace esto, pero dado que nuestra aplicación funciona de manera diferente (cambiamos el UIImageView), así que el gestureRecongnizer se configuró en el uiscrollview, que funciona bien, pero debes hacerlo en handleDoubleTap:

Esto se basa libremente en el código de ejemplo de Apple "TaptoZoom", pero como dije, necesitábamos nuestro reconocedor de gestos conectado a la vista de desplazamiento.

- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer { // double tap zooms in [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(handleSingleTap:) object:nil]; float newScale = [imageScrollView zoomScale] * 1.5; // Note we need to get location of the tap in the imageView coords, not the imageScrollView CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:imageView]]; [imageScrollView zoomToRect:zoomRect animated:YES]; }


Tenía algo similar y era porque no ajustaba los valores center.x y center.y al dividirlos también por la escala (usando center.x / scale y center.y / scale). Tal vez no estoy leyendo tu código correctamente.


Declare BOOL isZoom; in .h -(void)handleDoubleTap:(UIGestureRecognizer *)recognizer { if(isZoom){ CGPoint Pointview=[recognizer locationInView:self]; CGFloat newZoomscal=3.0; newZoomscal=MIN(newZoomscal, self.maximumZoomScale); CGSize scrollViewSize=self.bounds.size; CGFloat w=scrollViewSize.width/newZoomscal; CGFloat h=scrollViewSize.height /newZoomscal; CGFloat x= Pointview.x-(w/2.0); CGFloat y = Pointview.y-(h/2.0); CGRect rectTozoom=CGRectMake(x, y, w, h); [self zoomToRect:rectTozoom animated:YES]; [self setZoomScale:3.0 animated:YES]; isZoom=NO; } else{ [self setZoomScale:1.0 animated:YES]; isZoom=YES; } }