2011-02-09 28 views
39

Tôi đã triển khai thành công một lần thu nhỏ một lần xem. Tuy nhiên, chế độ xem không tự định vị vị trí mà tôi mong muốn. Đối với các stackoverflowers với một iPad, tôi muốn xem của tôi để được trung tâm như trên iPad Photos.app: khi bạn pinch & phóng to một album, các bức ảnh thể hiện mình trong một cái nhìn được mở rộng. Chế độ xem này được căn giữa với góc trên cùng bên phải trên ngón tay đầu tiên và ngón tay cái dưới cùng bên trái trên ngón tay kia. Tôi trộn nó với một bộ nhận diện pan, nhưng theo cách này người dùng luôn phải chụm, và sau đó xoay để điều chỉnh.UIPinchGestureRecognizer vị trí chế độ xem bị chèn ép giữa hai ngón tay

Dưới đây là lời giải thích vì đồ họa, tôi có thể gửi một đoạn video của ứng dụng của tôi nếu đó là không rõ ràng (có gì bí mật, tôi đang cố gắng để tạo lại Photos.app của iPad ...)

Vì vậy, đối với một ban đầu vị trí của các ngón tay, khởi điểm zoom:

enter image description here

Đây là thực tế "thu nhỏ" khung cho bây giờ. Quảng trường lớn, nhưng vị trí nằm dưới ngón tay

given the start position

Dưới đây là những gì tôi muốn làm: cùng kích thước, nhưng origin.x khác nhau và y:

enter image description here

(xin lỗi về kỹ năng photoshop kém của tôi ^^)

+0

HI Thomas, tôi cũng rất quan tâm đến điều đó. Bạn có tìm thấy giải pháp nào về nó không? Bạn có mã mẫu nào không? thx ~ – ludo

+2

Tôi chưa có thời gian để quay lại vấn đề này, nhưng câu trả lời @md_develop trông rất tuyệt. Tôi sẽ cố gắng tìm một số thời gian để cập nhật mã của tôi và chấp nhận câu trả lời nếu điều này làm việc –

Trả lời

41

Bạn có thể lấy CGPoint của trung điểm giữa hai ngón tay qua đoạn mã sau vào phương pháp handlingPinchGesture.

CGPoint point = [sender locationInView:self]; 

Toàn bộ phương pháp của tôi là handlePinchGesture.

/* 
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

làm thế nào điều này có thể hoạt động khi [người gửi locationInView: self] luôn luôn trả về cùng một điểm, điểm giữa giữa hai ngón tay bị kẹp? – Guy

+1

@Guy điểm giữa đang thay đổi sau 'UIGestureRecognizerStateBegan' vì bạn di chuyển ngón tay ra xa hoặc gần hơn. 'locationInView: self' trả về centroid giữa hai ngón tay. Phần đó hoạt động. Mặc dù sau 1 giờ tôi vẫn không thể làm điều này để làm việc trong ứng dụng của tôi, nơi tôi có nhiều lớp mà tôi cần phải di chuyển .. –

+1

Tôi đã sử dụng phương pháp này và chế độ xem được dịch chính xác. Tuy nhiên cách dịch nó không mượt mà như ứng dụng Ảnh –

11

Hãy xem qua số Touches sample project. Cụ thể các phương pháp này có thể giúp bạn:

// 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

cảm ơn, nhưng bằng cách sử dụng 'view.transform' thay đổi kích thước các bản xem trước của tôi ... Có cách nào để ngăn chặn điều đó không? –

+0

#import - Tôi cần điều này cho anchorPoint –

Các vấn đề liên quan