2010-03-05 60 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; 
      } 
     }