2010-03-05 18 views
5

Ứng dụng của tôi có UIScrollView với một chế độ xem phụ. Subview là một UIView mở rộng để in một trang PDF cho chính nó bằng cách sử dụng các lớp trong sự kiện drawLayer.UIScrollView zoomToRect không phóng to đến tận gốc (được tạo từ UITouch CGPoint)

Phóng to bằng cách sử dụng công cụ kẹp được tích hợp sẵn tuyệt vời. setZoomScale cũng hoạt động như mong đợi.

Tôi đã đấu tranh với chức năng zoomToRect. Tôi tìm thấy một ví dụ trực tuyến mà làm cho một biến zoomRect CGRect từ một CGPoint nhất định.

Khi chạm vàoChức năng được hiển thị, nếu có một lần nhấn đúp và tất cả chúng đều được thu nhỏ, tôi muốn phóng to PDFUIView mà tôi tạo ra như thể chúng đang véo với tâm của pinch nơi chúng được nhấn đúp .

Vì vậy, giả sử rằng tôi chuyển biến UITouch cho hàm của tôi sử dụng zoomToRect nếu chúng nhấn đúp.

tôi bắt đầu với các chức năng sau đây tôi tìm thấy trên táo trang web:

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

Sau đây là một phiên bản sửa đổi cho UIScrollView lớp mở rộng của tôi:

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

} 

Khi tôi làm điều này, UIScrollView dường như thu phóng bằng cách sử dụng cạnh dưới cùng bên phải của zoomRect ở trên và không phải là trung tâm.

Nếu tôi làm như thế này UIView

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

Hộp màu đỏ xuất hiện với các điểm tiếp xúc chết ở trung tâm.

Xin lưu ý: Tôi đang viết thư này từ máy tính của mình, tôi nhớ lại việc chia nhỏ hai phần trên máy Mac của tôi, vì vậy hãy giả sử rằng điều này vẽ thẳng với điểm tiếp xúc ở giữa. Nếu UIView đã vẽ ra khỏi trung tâm nhưng thu nhỏ đến đúng chỗ nó sẽ là tất cả tốt.

Tuy nhiên, điều gì sẽ xảy ra là khi nó chỉnh sửa zoomToRect, dường như sử dụng góc dưới cùng bên phải của zoomRect ở trên cùng bên trái của kết quả được phóng to.

Ngoài ra, tôi nhận thấy rằng tùy thuộc vào nơi tôi nhấp vào UIScrollView, nó neo đến các điểm khác nhau. Nó gần như có vẻ như có một chéo xuống giữa và nó phản ánh các điểm bằng cách nào đó như bất cứ nơi nào còn lại của giữa là một phản ánh tiêu cực và bất cứ nơi nào bên phải của trung là một sự phản ánh tích cực?

Điều này có vẻ phức tạp, không nên nó chỉ thu phóng đến trực tiếp được rút ra khi UIView có thể vẽ?

Tôi đã sử dụng rất nhiều nghiên cứu để tìm hiểu cách tạo PDF có quy mô chất lượng cao, vì vậy tôi giả định rằng việc sử dụng CALayer có thể đang ném ra khỏi hệ tọa độ? Nhưng với UIScrollView nó chỉ nên coi nó như một khung nhìn với kích thước 768x985.

Đây là loại nâng cao, hãy giả sử mã để tạo zoomRect là tất cả đều tốt. Có một cái gì đó sâu hơn với CALayer trong UIView mà là trong UIScrollView ....

Trả lời

0

Tôi đã có một cái gì đó tương tự và đó là vì tôi đã không điều chỉnh các giá trị center.x và center.y bằng cách chia chúng cho quy mô cũng (sử dụng center.x/scale và center.y/scale). Có lẽ tôi không đọc mã của bạn đúng.

0

Tôi đang có hành vi tương tự và nó khá bực bội ... Hình chữ nhật được đưa vào UIScrollView là hoàn hảo .. nhưng quan điểm của tôi, bất kể tôi làm gì liên quan đến việc thay đổi zoomScale lập trình luôn thu phóng và chia tỷ lệ thành tọa độ 0,0, không có vấn đề gì.

Tôi đã thử thay đổi zoomScale, tôi đã thử zoomToRect, tôi đã thử tất cả, và mỗi phút tôi chạm vào zoomScale trong mã, nó sẽ đi phối hợp 0,0.

Tôi cũng phải thêm và rõ ràng setContentSize vào hình ảnh đã chỉnh kích thước trong scrollview sau khi thao tác phóng to hoặc nếu không tôi không thể cuộn sau khi thu phóng hoặc chụm.

Đây có phải là lỗi trong 3.1.3 hay không?

1

Tôi nhận thấy rằng quả táo bạn đang sử dụng không phóng to đúng cách nếu hình ảnh bắt đầu ở zoomScale nhỏ hơn 1 vì nguồn gốc zoomRect không chính xác. Tôi đã chỉnh sửa nó để hoạt động chính xác. Đây là mã:

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

Điều quan trọng là phần này nhân giá trị trung tâm của (2 - self.minimumZoomScale). Hy vọng điều này sẽ hữu ích.

+0

cuối bình luận, nhưng tôi không thể cưỡng lại; nếu điều này hoạt động: đó là may mắn tinh khiết. Nhân tọa độ của một trung tâm không có ý nghĩa gì cả. Nếu bạn cần thực hiện bản dịch trên một trung tâm, bạn sẽ thêm giá trị thay thế. Nhưng rất có thể, trung tâm không chính xác vì nó được tính toán từ tham chiếu hệ tọa độ sai (ví dụ: từ góc nhìn sai) – jyavenard

0

Trong trường hợp của tôi đó là:

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

Ok câu trả lời khác:

Quả táo cung cấp các công trình thường xuyên đối với tôi, nhưng bạn cần phải có nhận dạng cử chỉ chuyển đổi các điểm tap vào coords IMAGExem - không phải để cuộn.

dụ của Apple thực hiện điều này, nhưng kể từ khi ứng dụng của chúng tôi làm việc khác nhau (chúng ta thay đổi UIImageView), do đó gestureRecongnizer được thành lập trên UIScrollView - mà hoạt động tốt, nhưng bạn cần phải làm điều này trong handleDoubleTap:

Điều này dựa trên mã ví dụ táo "TaptoZoom", nhưng như tôi đã nói, chúng tôi cần trình nhận dạng cử chỉ của chúng tôi được kết nối với chế độ xem cuộn.

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

Cảm ơn @Tom, chuyển vị trí sang chế độ xem hình ảnh đã hoạt động! – Motasim

+0

Điều này thật tuyệt. Đã làm cho tôi. –

0

Tôi đã thử các giải pháp khác nhau, nhưng điều này có vẻ là độ phân giải tốt nhất Nó thực sự thẳng về phía trước và thụ thai?

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

Tôi không đồng ý với một trong các nhận xét ở trên nói rằng bạn không bao giờ nên nhân tọa độ của trung tâm theo một số yếu tố.

Giả sử bạn hiện đang hiển thị toàn bộ hình ảnh 400x400px hoặc tệp PDF trong chế độ xem cuộn 100x100 và muốn cho phép người dùng tăng gấp đôi kích thước của nội dung cho đến khi nó là 1: 1. Nếu bạn nhấn đúp vào điểm (75,75), bạn mong đợi hình chữ nhật được phóng to có nguồn gốc 100,100 và kích thước 100x100 trong chế độ xem nội dung 200x200 mới. Vì vậy, điểm khai thác ban đầu (75,75) bây giờ là (150,150) trong không gian 200x200 mới. Bây giờ, sau khi thao tác zoom # 1 đã hoàn thành, nếu bạn nhấn đúp lần nữa (75,75) bên trong hình chữ nhật 100x100 mới (là hình vuông góc dưới bên phải của hình chữ nhật lớn hơn 200x200), bạn mong đợi người dùng được hiển thị hình vuông 100x100 dưới cùng bên phải của hình ảnh lớn hơn, hình ảnh này giờ đây sẽ được thu phóng thành 400x400 pixel.Để tính toán xuất xứ của hình chữ nhật 100x100 mới nhất trong hình chữ nhật lớn hơn 400x400, bạn cần cân nhắc tỷ lệ và tỷ lệ nội dung hiện tại (kể từ trước hành động zoom cuối cùng này, chúng tôi hiển thị hình chữ nhật 100x100 dưới cùng bên phải trong một Hình chữ nhật nội dung 200x200).

Vì vậy, tọa độ x của hình chữ nhật cuối cùng sẽ là: center.x/currentScale - (scrollView.frame.size.width/2) + scrollView.contentOffset.x/currentScale = 75/.5 - 100/2 + 100/.5 = 150 - 50 + 200 = 300.

Trong trường hợp này, là hình vuông, phép tính cho toạ độ y là như nhau. Và chúng tôi đã thực sự phóng to hình chữ nhật dưới cùng bên phải 100x100, trong đó, trong chế độ xem nội dung 400x400 lớn hơn có nguồn gốc 300,300.

Vì vậy, đây là cách bạn sẽ tính kích thước và hình chữ nhật thu phóng: 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; 

Hy vọng điều này có ý nghĩa; thật khó để giải thích nó bằng văn bản mà không cần phác thảo ra các hình vuông/hình chữ nhật khác nhau.

Chúc mừng, Raf Colasante

4
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; 
      } 
     } 
Các vấn đề liên quan