2011-02-09 10 views
39

Pomyślnie zaimplementowałem zbliżenie z powiększeniem widoku. Jednak widok nie jest ustawiony tak, jak chciałbym. W przypadku stackoverflowers z iPadem chciałbym, aby mój widok był wyśrodkowany jak na iPhonie Photos.app: kiedy zbliżasz się do powiększonego albumu, zdjęcia prezentują się w widoku, który się rozwija. Ten widok jest w przybliżeniu wyśrodkowany w prawym górnym rogu pierwszego palca i dolnego lewego palca na drugim palcu. Zmieszałem go z wykrywaczem patelni, ale w ten sposób użytkownik zawsze musi uszczypnąć, a następnie przesuwać w celu dostosowania.UIPinchGestureRecognizer umieszcza ucięty widok między dwoma palcami

Oto więc graficzny wyjaśnienie, mogę zamieścić film z mojej aplikacji, czy to jasne (nie jest tajemnicą, próbuję odtworzyć Photos.app iPad ...)

Więc dla wstępna pozycja palców, Początek powiększanie:

enter image description here

to jest rzeczywista „powiększony” rama do teraz. Kwadrat jest większy, ale pozycja jest poniżej palców

given the start position

Oto co chciałbym mieć taki sam rozmiar, ale różni origin.x i y:

enter image description here

(przykro mi z powodu moich słabych umiejętności w zakresie Photoshopa ^^)

+0

HI Thomas, bardzo mnie to interesuje. Czy znalazłeś jakieś rozwiązanie na ten temat? Czy masz jakieś kody próbek? thx ~ – ludo

+2

Nie miałem czasu, aby wrócić do tego problemu, ale odpowiedź @md_develop wygląda świetnie. Spróbuję znaleźć trochę czasu, aby zaktualizować mój kod i zaakceptować odpowiedź, jeśli to zadziała –

Odpowiedz

41

można uzyskać CGPoint punktu środkowego pomiędzy dwoma palcami za pomocą następującego kodu w metodzie handlingPinchGesture.

CGPoint point = [sender locationInView:self]; 

Moja cała metoda handlePinchGesture znajduje się poniżej.

/* 
instance variables 

CGFloat lastScale; 
CGPoint lastPoint; 
*/ 

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender { 
    if ([sender numberOfTouches] < 2) 
     return; 

    if (sender.state == UIGestureRecognizerStateBegan) { 
     lastScale = 1.0; 
     lastPoint = [sender locationInView:self]; 
    } 

    // Scale 
    CGFloat scale = 1.0 - (lastScale - sender.scale); 
    [self.layer setAffineTransform: 
     CGAffineTransformScale([self.layer affineTransform], 
           scale, 
           scale)]; 
    lastScale = sender.scale; 

    // Translate 
    CGPoint point = [sender locationInView:self]; 
    [self.layer setAffineTransform: 
     CGAffineTransformTranslate([self.layer affineTransform], 
            point.x - lastPoint.x, 
            point.y - lastPoint.y)]; 
    lastPoint = [sender locationInView:self]; 
} 
+1

jak mogłoby to praca, gdy [nadawca locationInView: self] zawsze zwraca ten sam punkt, punkt w połowie między dwoma uciskających palców? – Guy

+1

@Guy midpoint zmienia się po 'UIGestureRecognizerStateBegan', ponieważ przesuwasz palce z dala lub bliżej. 'locationInView: self' zwraca środek ciężkości między dwoma palcami. Ta część działa. Chociaż po 1 godzinie nadal nie mogę tego uruchomić w mojej aplikacji, gdzie mam kilka warstw, które muszę przenieść .. –

+1

Użyłem tej metody, a widok jest poprawnie przetłumaczony. Jednak sposób, w jaki tłumaczone nie jest gładka jak Photo app –

11

Spójrz na Touches sample project. W szczególności te metody mogą pomóc:

// scale and rotation transforms are applied relative to the layer's anchor point 
// this method moves a gesture recognizer's view's anchor point between the user's fingers 
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { 
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { 
     UIView *piece = gestureRecognizer.view; 
     CGPoint locationInView = [gestureRecognizer locationInView:piece]; 
     CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview]; 

     piece.layer.anchorPoint = CGPointMake(locationInView.x/piece.bounds.size.width, locationInView.y/piece.bounds.size.height); 
     piece.center = locationInSuperview; 
    } 
} 

// scale the piece by the current scale 
// reset the gesture recognizer's rotation to 0 after applying so the next callback is a delta from the current scale 
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer 
{ 
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer]; 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { 
     [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]); 
     [gestureRecognizer setScale:1]; 
    } 
} 
+0

dzięki, ale użycie 'view.transform' zmienia również moje subviews ... Czy istnieje sposób, aby temu zapobiec? –

+0

#import - Musiałem to dla Anchorpoint –

Powiązane problemy