Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone UIScrollView zoomToRect未缩放到给定的矩形(从UITouch CGPoint创建)_Iphone_Uiscrollview_Calayer - Fatal编程技术网

Iphone UIScrollView zoomToRect未缩放到给定的矩形(从UITouch CGPoint创建)

Iphone UIScrollView zoomToRect未缩放到给定的矩形(从UITouch CGPoint创建),iphone,uiscrollview,calayer,Iphone,Uiscrollview,Calayer,我的应用程序有一个UIScrollView和一个子视图。子视图是一个扩展的UIView,它使用drawLayer事件中的层将PDF页面打印到自身 使用内置的pinching进行缩放效果非常好。setZoomScale也按预期工作 我一直在努力使用zoomToRect函数。我在网上找到了一个示例,它从给定的CGPoint生成一个CGRect zoomRect变量 在touchesEnded函数中,如果有一个双击,并且它们一直被缩小,我想放大到我创建的PDFUIView,就像它们在双击的挤压中心被挤

我的应用程序有一个UIScrollView和一个子视图。子视图是一个扩展的UIView,它使用drawLayer事件中的层将PDF页面打印到自身

使用内置的pinching进行缩放效果非常好。setZoomScale也按预期工作

我一直在努力使用zoomToRect函数。我在网上找到了一个示例,它从给定的CGPoint生成一个CGRect zoomRect变量

在touchesEnded函数中,如果有一个双击,并且它们一直被缩小,我想放大到我创建的PDFUIView,就像它们在双击的挤压中心被挤压一样

因此,假设我将UITouch变量传递给我的函数,如果它们双击,该函数将使用zoomToRect

我从苹果网站上的以下功能开始:

以下是my 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 *v = [[UIView alloc] initWithFrame:zoomRect]; 
[v setBackgroundColor:[UIView redColor]];
[self addSubview:v];
红色框显示,接触点位于中间

请注意:我是在我的电脑上写这篇文章的,我记得在我的Mac电脑上乱搞了除以2的部分,所以假设这画了一个矩形,接触点在中间。如果UIView偏离中心,但放大到正确的位置,则一切正常

但是,当它执行zoomToRect时,它似乎使用了放大结果左上角zoomRect的右下角

此外,我注意到,根据我在UIScrollView上单击的位置,它会定位到不同的点。似乎中间有一个十字,它以某种方式反映了这些点,好像中间左边的任何地方都是负面反映,中间右边的任何地方都是正面反映

这似乎很复杂,难道它不应该缩放到UIView能够绘制的矩形吗

我用了大量的研究来找出如何创建高质量的PDF,所以我假设使用CALayer可能会偏离坐标系?但对于UIScrollView,它应该将其视为具有768x985维度的视图


这有点高级,请假设创建zoomRect的代码都很好。UIScrollView中的UIView中的CALayer有一些更深层次的东西…

我有一些类似的东西,这是因为我没有通过将center.x和center.y值除以刻度来调整它们(使用center.x/scale和center.y/scale)。也许我没有正确地阅读您的代码。

我也有同样的行为,这很令人沮丧。。。正在馈送到UIScrollView的矩形非常完美。。然而,在我看来,无论我做什么,只要涉及到以编程方式更改zoomScale,无论发生什么情况,都会缩放到坐标0,0

我试过改变zoomScale,我试过zoomToRect,我试过所有这些,每一次我在代码中触摸zoomScale的那一分钟,它都会转到坐标0,0

在缩放操作后,我还必须在scrollview中的已调整大小的图像中添加和显式设置ContentSize,否则,在缩放或收缩后我将无法滚动


这是3.1.3中的错误还是什么?

我注意到,如果图像的缩放比例小于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)。 希望这能有所帮助。

在我的例子中:

zoomRect.origin.x    = center.x / self.zoomScale - (zoomRect.size.width  / 2.0);
zoomRect.origin.y    = center.y / self.zoomScale  - (zoomRect.size.height / 2.0);
好的,另一个答案是:

苹果提供的程序对我来说很有用,但你需要让手势识别器将点击点转换为imageView坐标,而不是滚动条

苹果的例子就是这样做的,但由于我们的应用程序工作方式不同(我们更改了UIImageView),因此在uiscrollview上设置了gestureRecongnizer-这很好,但您需要在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];
}

我尝试过不同的解决方案,但这看起来是最好的解决方案 这真的是直截了当的概念

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

我不同意上面的一条评论,即你永远不应该用某个因子乘以中心的坐标

假设您当前正在100x100滚动视图中显示整个400x400px图像或PDF文件,并希望允许用户将内容的大小增加一倍,直到其为1:1。 如果双击点(75,75),则在新的200x200内容视图中,放大的矩形的原点为100100,大小为100x100。因此,原来的分接点(75,75)现在(150150)在新的200x200空间中

现在,在缩放操作#1完成后,如果您再次双击新的100x100矩形(大200x200矩形的右下角正方形)内的(75,75),您希望向用户显示大图像的右下角100x100正方形,该正方形现在将缩放到400x400像素

为了计算这个最新的100x100矩形在较大的400×400矩形内的原点,你需要考虑缩放和当前内容偏移量(因为在最后的缩放动作之前,我们在200×200的内容矩形内显示右下100x100矩形)。p> 因此,最终矩形的x坐标变为: center.x/currentScale-(scrollView.frame.size.width/2)+scrollView.contentOffset.x/currentScale =75/.5-100/2+100/.5=150-50+200=300

在这种情况下,作为正方形,y坐标的计算是相同的。 我们确实放大了右下角的100x100矩形,在更大的400x400内容视图中,它有orig
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;
   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;
            }
        } 
func getRectForVisibleView() -> CGRect {
    var visibleRect: CGRect = .zero
    
    visibleRect.origin = self.contentOffset
    visibleRect.size = self.bounds.size

    let theScale = 1.0 / self.zoomScale
    visibleRect.origin.x *= theScale
    visibleRect.origin.y *= theScale
    visibleRect.size.width *= theScale
    visibleRect.size.height *= theScale
    
    return visibleRect
}

func moveToRect(rect: CGRect) {
    let scale = self.bounds.width / rect.width
    self.zoomScale = scale
    self.contentOffset = .init(x: rect.origin.x * scale, y: rect.origin.y * scale)
}