6
votes

UiscrollView zoomtorect ne pas zoomer sur le rect donné (créé à partir de UITOUCH CGPoint)

Mon application a un Uiscrollview avec une sous-vision. La sous-visVIEW est une UIView étendue qui imprime une page PDF à l'aide de couches dans l'événement DrawLayer.

Zoom à l'aide de la pince intégrée fonctionne bien. SetzoomCale fonctionne également comme prévu. P>

J'ai eu du mal avec la fonction Zoomtorect. J'ai trouvé un exemple en ligne qui fait une variable de zoomrect CGRRECT à partir d'un CGPoint donné. p>

dans la fonction touchée, s'il y avait un double robinet et qu'elles sont complètement zoomées, je veux zoomer sur ce PDFuivievie que j'ai créé comme s'il s'agissait de pincer avec le centre de la pincée où Ils ont doublé taraudé. P>

Supposez donc que je passe la variable UITOUCH à ma fonction qui utilise zoomporect si elles double appuyez sur. P>

J'ai commencé avec la fonction suivante que j'ai trouvée sur le site de pépendant:

http: // développeur .apple.com / iPhone / iPhone / Library / Documentation / conceptuel / Uiscrollview_pg / Zoomzoom / Zoomzoom.html P>

Ce qui suit est une version modifiée pour My Uiscrollview Classe étendue: P> xxx pré>

Lorsque je fais cela, l'UISCrollView semble zoomer à l'aide du bord inférieur droit du zoomrect ci-dessus et non du centre. p>

Si je fais uiview comme ça p >

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


0 commentaires

9 Réponses :


0
votes

J'avais quelque chose de similaire et c'était parce que je n'ai pas ajusté les valeurs Centre.x et Center.Y en les divisant par la balance également (à l'aide de Centre.x / Balance et de Centre.Y / Échelle). Peut-être que je ne lis pas votre code à droite.


0 commentaires

0
votes

J'ai le même comportement et c'est assez frustrant ... Le rectangle étant nourri à l'Uiscrollview est parfait .. My View, peu importe ce que je fais tout ce que je fais tout ce qui implique de changer de zoomscale Toujours zoom surmatiquement et des échelles pour coordonner 0,0, peu importe quoi.

J'ai essayé de changer le zoomcale, j'ai essayé Zoomtorect, je les ai tous essayés, et chaque minute, je touche le zoomscale en code, il va coordonner 0,0.

J'ai également dû ajouter et définir explicite setContint à l'image redimensionnée dans la vision de ScrollView après une opération de zoom, sinon je ne peux pas faire défiler après un zoom ou une pincée.

Est-ce un bogue en 3.1.3 ou quoi?


0 commentaires

1
votes

J'ai remarqué que l'apple que vous utilisez ne zoomez pas correctement si l'image commence à un zoomscale inférieur à 1 car l'origine Zoomrector est incorrecte. Je l'ai édité pour travailler correctement. Voici le code:

- (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;
}


1 commentaires

commentaire tardif, mais je ne pouvais pas résister; Si cela fonctionne: c'est une chance pure. Multiplier la coordonnée d'un centre n'a rien de significatif. Si vous devez effectuer une traduction sur un centre, vous ajoutez une valeur à la place. Mais probablement, le centre est incorrect car il a été calculé à partir de la mauvaise référence du système de coordonnées (par exemple de la mauvaise vue)



1
votes

Dans mon cas, c'était:

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


0 commentaires

5
votes

OK Une autre réponse:

La routine fournie par Apple fonctionne pour moi, mais vous devez disposer de la reconnaissance de la gestes, convertir le point de prise sur les coordonnées imageview - non sur le défileur. P>

L'exemple de Apple fait cela, mais depuis notre application fonctionne différemment (nous modifions l'UIImageView), de sorte que le gestantecongnizer a été configuré sur l'UISCrollView - qui fonctionne bien, mais vous devez le faire dans la mainDoubleTAP:

Ceci est sur la base du code d'exemple Apple "Tapozoom", mais comme je l'ai dit, nous avions besoin de notre reconnaissance de geste reconnaissant à la vue de défilement. P>

- (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];
}


2 commentaires

Merci @TOM, convertissant l'emplacement à la vue Image a fonctionné!


C'est bien. Travaillé pour moi.



0
votes

J'ai essayé différentes solutions, mais cela semble la meilleure résolution Il est vraiment simple et conceptionnel? XXX


0 commentaires

0
votes

Je suis en désaccord avec l'un des commentaires ci-dessus en disant que vous ne devriez jamais multiplier les coordonnées du Centre par un facteur.

Dites que vous affichez actuellement une image de 400x400px ou un fichier PDF dans une vue de défilement de 100x100 et que vous souhaitez autoriser le Les utilisateurs doivent doubler la taille du contenu jusqu'à ce qu'il soit 1: 1. Si vous double appuyez sur le point (75,75), vous vous attendez à ce que le rectangle zoom-in ait l'origine 100 100 et la taille 100x100 dans la nouvelle vue de contenu 200x200. Donc, le point de départ d'origine (75,75) est maintenant (150.150) dans le nouvel espace 200x200.

Maintenant, après que Zoom Action n ° 1 a terminé, si vous tapez à nouveau sur (75,75) à l'intérieur. Le nouveau rectangle 100x100 (qui est le carré inférieur droit du plus grand rectangle 200x200), vous vous attendez à ce que l'utilisateur soit affiché sur le carré 100x100 inférieur de l'image plus grande, qui deviendrait maintenant zoom sur 400x400 pixels.

Afin de calculer l'origine de ce dernier rectangle 100x100 dans le plus grand rectangle 400x400, vous devez envisager le décalage de la balance et du contenu actuel (depuis précédant cette dernière action de zoom, nous affichons le rectangle 100x100 à droite de 200x200. Rectangle de contenu).

Donc, la coordonnée X du dernier rectangle devient: Center.x / Currentscale - (Scrollview.frame.size.Width / 2) + ScrollView.Contentoffset.x / Currentscale = 75 / .5 - 100/2 + 100 / .5 = 150 - 50 + 200 = 300.

Dans ce cas, étant un carré, le calcul de la coordonnée y est identique. Et nous avons effectivement zoomer dans le rectangle 100x100 inférieur droit, qui, dans la vue de contenu plus grande 400x400, a l'origine 300 300.

Voici comment vous allez calculer la taille et l'origine du rectangle de zoom: zoomrect.size.height = mscrollview.frame.size.height / échelle; zoomrect.size.width = mscrollview.frame.size.width / échelle; xxx

espère que cela a eu du sens; Il est difficile de l'expliquer par écrit sans dessiner les divers carrés / rectangles.

acclamations, RAF COLASANTE


0 commentaires

4
votes
   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;
            }
        } 

0 commentaires

1
votes

Extension UiscrollView {

func getRectForVisibleView() -> CGRect {
    var visibleRect: CGRect = .zero
    
    visibleRect.origin = self.contentOffset
    visibleRect.size = self.bounds.size

    let theScale = 1.0 / self.zoomScale
    visibleRect.origin.x *= theScale
    visibleRect.origin.y *= theScale
    visibleRect.size.width *= theScale
    visibleRect.size.height *= theScale
    
    return visibleRect
}

func moveToRect(rect: CGRect) {
    let scale = self.bounds.width / rect.width
    self.zoomScale = scale
    self.contentOffset = .init(x: rect.origin.x * scale, y: rect.origin.y * scale)
}


1 commentaires

Veuillez ne pas publier que le code comme réponse, mais fournissez également une explication de votre code et de la manière dont il résout le problème de la question. Les réponses avec une explication sont généralement plus utiles et de meilleure qualité, et sont plus susceptibles d'attirer des upvotes.