为什么平移操作可以让用户将缩放后的视图移动到父视图之外?

4

我正在开发PDF页面上的捏合缩小和放大功能。我的捏合缩小和平移(移动)功能正常工作,但当用户不断移动缩放视图时,缩放视图会超出父级视图的边界。就像这样:

theis is the move user made after zoom

如何限制平移移动,以便用户无法将缩放的视图/PDF移动到超级视图之外。
我正在使用的相关代码是:

// This method will handle the PINCH / ZOOM gesture 

- (void)pinchZoom:(UIPinchGestureRecognizer *)gestureRecognizer {
    if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
        // Reset the last scale, necessary if there are multiple objects with different scales
        lastScale = [gestureRecognizer scale];
    }
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {

    if (!zoomActive) {
        zoomActive = YES;
        panActive = YES;
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panMove:)];
        [panGesture setMaximumNumberOfTouches:2];
        [panGesture setDelegate:self];
        [self addGestureRecognizer:panGesture];
        [panGesture release];

    }

            CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];

            // Constants to adjust the max/min values of zoom
            const CGFloat kMaxScale = 2.0;
            const CGFloat kMinScale = 1.0;

            CGFloat newScale = 1 -  (lastScale - [gestureRecognizer scale]); 
            newScale = MIN(newScale, kMaxScale / currentScale);   
            newScale = MAX(newScale, kMinScale / currentScale);
            CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
            [gestureRecognizer view].transform = transform;

            lastScale = [gestureRecognizer scale];  // Store the previous scale factor for the next pinch gesture call 



    [delegate leavesView:self zoomingCurrentView:[gestureRecognizer scale]];            




}

}
我处理平移的方法:

// This method will handle the PAN / MOVE gesture 
- (void)panMove:(UIPanGestureRecognizer *)gestureRecognizer  
{  
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)   {  
        CGPoint translation = [gestureRecognizer translationInView:[[gestureRecognizer view] superview]];  
        [[gestureRecognizer view] setCenter:CGPointMake([[gestureRecognizer view] center].x + translation.x, [[gestureRecognizer view] center].y + translation.y)];  

        [gestureRecognizer setTranslation:CGPointZero inView:[[gestureRecognizer view] superview]];  
    }  
}  

请建议如何处理在其父视图边界内限制拖动/移动的平移。
2个回答

3
在你的 panMove 方法中尝试这段代码。在我的情况下它可以正常工作。
        static CGPoint initialCenter;

        if (recognizer.state == UIGestureRecognizerStateBegan)
        {
            initialCenter = recognizer.view.center;
        }

        CGPoint translation = [recognizer translationInView:recognizer.view];
        CGPoint newCenter = CGPointMake(initialCenter.x + translation.x,
                                       initialCenter.y + translation.y);
        CGRect newFrame = recognizer.view.frame;
        CGRect superViewBounds = recognizer.view.superview.bounds;
        CGPoint superViewOrigin = recognizer.view.superview.frame.origin;

        if(newCenter.x-(newFrame.size.width/2) >= (superViewBounds.size.width+superViewOrigin.x)-200 /*right*/
           ||
           newCenter.x+(newFrame.size.width/2) <= (superViewOrigin.x+200) /*left*/
           ||
           newCenter.y-(newFrame.size.height/2) >= (superViewBounds.size.height+superViewOrigin.y)-200 /*bottom*/
            ||
            newCenter.y+(newFrame.size.height/2) <= (superViewOrigin.y+100)) /*top*/
        {
            return;
        }else{
            recognizer.view.center = newCenter;
        }

这个100、200和所有的是什么? - Sneha
@Sneha 我将100更改为视图的view.frame.width,以避免超出superview,将200更改为view.frame.height,这对我有用。但是,如果您像我一样也使用了pinch和rotation,则需要进行一些额外的工作。 - Lexi

0
你可以在代码中添加类似于以下内容的语句:(这可能有些粗糙,因此您可能需要解决一些错误)
if([gestureRecognizer view].frame.bounds.x < self.view.bounds.x - panExapantion)
{ 
    //then don't move it
}

//... repeat this for all sides (this is left), bottom, right, and top.

编辑: 好的,考虑一个盒子内部有一个盒子,因此我们有一个内部盒子和一个外部盒子。如果我们不希望内部盒子超出外部盒子,则必须使所有这些语句都为真:

  1. 内部盒子的移动左侧未超出外部盒子的左侧。
  2. 内部盒子的移动右侧未超出外部盒子的右侧。
  3. 内部盒子的移动底部未超出外部盒子的底部。
  4. 内部盒子的移动顶部未超出外部盒子的顶部。

在您的情况下,PDF 是内部盒子,iPad 是外部盒子。为了防止 PDF 超出盒子,我们需要检查每个语句是否为真,如果其中一个为假,则不将 PDF 移动到其新位置,或者将 PDF 移动到 iPhone 屏幕边缘附近。

问题在于如果使用捏合和缩放,那么盒子突然就会一直在外部盒子之外,那么我们该如何解决呢?我们需要知道当内部盒子被缩放时添加了多少像素(为了方便说明,让我们称之为扩展)。因此,我们需要知道盒子的扩展量,并将其减去。就像这样:(这是一个简化的if语句,在代码中不起作用)
If(outerBox.leftSide is less than innerBox.leftSide - panExpantion) 
{
    //Then the innerBox is outside the outterBox
}

我希望这有所帮助,让事情更加清晰明了!


如何在四个方向上工作?我以为我们只有两个轴?你能解释一下或者发布一个教程吗? - Hosni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接