2010-03-05 87 views
5

我的應用程序有一個子視圖的UIScrollView。子視圖是一個擴展的UIView,它使用drawLayer事件中的圖層將PDF頁面打印到自己。UIScrollView zoomToRect沒有縮放到給定矩形(從UITouch CGPoint創建)

使用內置夾捏變焦效果很好。 setZoomScale也按預期工作。

我一直在努力與zoomToRect函數。我在網上找到了一個例子,它從給定的CGPoint創建CGRect的zoomRect變量。

在touchesEnded函數中,如果出現了雙擊並且它們全部縮小,我想放大到我創建的那個PDFUIView,就好像它們正在擠壓雙中心一樣。 。

因此,假設我將UITouch變量傳遞給我的函數,該函數利用zoomToRect,如果它們雙擊。

我開始用下面的功能我在蘋果網站上發現:

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

下面是修改後的版本爲我的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]; 

} 

當我做到這一點, UIScrollView似乎使用zoomRect的右下邊緣而不是中心進行縮放。

如果我做的UIView這樣

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

紅色框顯示了觸摸點在中心死亡。

請注意:我從我的電腦上寫下了這個消息,我記得在我的Mac上把它分成了兩部分,所以我們假設這會在中間點觸摸一個矩形。如果UIView退出中心但放大到正確的位置,那將會很好。

但是,會發生什麼情況是,當它執行zoomToRect時,似乎使用放大結果左上角的縮放右下角的右下角。

此外,我注意到,根據我點擊UIScrollView的位置,它錨定到不同的點。幾乎看起來中間有一個十字架,它以某種方式反映這些點,好像中間的任何一個地方都是負面反射,而中間的任何一個地方都是正面的反射?

這似乎很複雜,不應該只是放大到UIView能夠繪製的矩形?

我用了大量的研究來弄清楚如何創建一個高質量的PDF,所以我假設使用CALayer可能會丟掉座標系?但對於UIScrollView,它應該將其視爲768x985尺寸的視圖。

這是一種先進的,請假設創建zoomRect的代碼都很好。在UIView中的CALayer有一些東西在UIScrollView中......

回答

0

我有類似的東西,這是因爲我沒有通過將center.x和center.y的值除以也使用中心(使用center.x/scale和center.y/scale)。也許我沒有正確讀取你的代碼。

0

我有相同的行爲,這是相當令人沮喪的...被饋送到UIScrollView的矩形是完美的..但我的觀點,無論我做什麼,涉及以編程方式改變zoomScale總是放大和縮放到無論如何座標0,0。

我試過只是改變zoomScale,我試過zoomToRect,我已經嘗試過所有的,每一次我在代碼中觸摸zoomScale,它會去座標0,0。

我也必須在縮放操作後在scrollview中爲縮放後的圖像添加顯式setContentSize,否則我無法在縮放或縮放後滾動。

這是3.1.3中的錯誤還是什麼?

1

我注意到,如果圖像是以小於1的縮放比例開始的,因爲zoomRect原點不正確,所以您使用的蘋果不能正確縮放。我編輯它才能正常工作。這裏的代碼:

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

關鍵是這部分乘以(2 - self.minimumZoomScale)的中心值。 希望這有助於。

+0

末評論,但我無法抗拒;如果這是有效的:這是純粹的運氣。乘中心的座標沒有意義。如果您需要在中心上執行翻譯,請改爲添加一個值。但最有可能的是,該中心是不正確的,因爲它是從錯誤的座標系引用計算出來的(例如,從錯誤的視圖) – jyavenard 2011-09-12 08:55:10

0

在我的情況是:

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

好了另一個答案:

提供日常工作對我來說,蘋果,但是你需要有手勢識別抽頭點轉換爲ImageView的COORDS - 不是滾動條。

蘋果的例子做到這一點,但由於我們的應用程序的工作方式不同(我們改變的UIImageView),所以gestureRecongnizer成立的UIScrollView的 - 這工作得很好,但你需要這樣做的handleDoubleTap:

這是鬆散的基於蘋果示例代碼「TaptoZoom」,但正如我所說,我們需要我們的手勢識別器連接到滾動視圖。

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

感謝@Tom,將位置轉換爲圖像視圖! – Motasim 2012-02-13 07:15:36

+0

這太好了。爲我工作。 – 2012-10-27 23:25:33

0

我已經嘗試了不同的解決方案,但這個看起來這實在是直線前進的,概念性的最佳分辨率 ?

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

我不同意上面的評論之一,說你永遠不應該乘以中心座標的一些因素。

假設您目前正在100x100滾動視圖中顯示整個400x400px圖片或PDF文件,並且希望允許用戶將內容大小加倍,直到它爲1:1。 如果雙擊點(75,75),則預計放大的矩形在新的200x200內容視圖中具有原點100,100和大小100x100。因此,在新的200x200空間中,原始點(75,75)現在(150,150)。

現在,在縮放操作#1完成後,如果再次在新的100x100矩形(這是較大的200x200矩形的右下方平方)內雙擊(75,75),您希望用戶將顯示較大圖像的右下方100x100平方,現在將放大到400x400像素。

爲了計算最大的100x100矩形在最大的400x400矩形內的原點,您需要考慮縮放和當前內容偏移(因爲在最後一次縮放操作之前,我們在右下方顯示右下角的100x100矩形200x200內容矩形)。

所以在x最終矩形的座標變成: center.x/currentScale - (scrollView.frame.size.width/2)+ scrollView.contentOffset.x/currentScale = 75/0.5 - 100/2 + 100/.5 = 150 - 50 + 200 = 300.

在這種情況下,作爲正方形,y座標的計算是相同的。 而且我們確實放大了右下角的100x100矩形,在較大的400x400內容視圖中,它的起點爲300,300。

因此,這裏是你將如何計算變焦矩形的大小和來源: zoomRect.size.height = mScrollView.frame.size.height /規模; 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; 

希望這是有道理的;如果不繪製各種方塊/矩形,很難用書面的方式來解釋它。

乾杯, 拉夫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; 
      } 
     }