2011-04-04 67 views
0

我有几个视图可以拖动,旋转,缩放。我想做到这一点,所以他们不能药物,旋转或缩小屏幕。检测CGAffineTransformed视图是否超出屏幕/ UIView的界限

拖动似乎不是一个问题,因为我没有使用变换来生成新的位置,并看看这个新的位置是否会把视图从屏幕上。

当我旋转或缩放我使用CGAffineTransform(CGAffineTransformedRotate或CGAffineTransformScale),我似乎无法得到什么新的框架将实际应用到我的看法。

CGRect newElementBounds = CGRectApplyAffineTransform(element.bounds, CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale])); 


CGRect elementBoundsInSuperView = [element convertRect:newElementBounds toView:[element superview]]; 

elementBoundsInSuperView不是我期待它的Rect,它的方式关闭。

我也试图先在SuperView中获取边界,然后对其应用转换,但这也不正确。

CGRect elementBoundsInSuperView = [element convertRect:element.bounds toView:[element superview]]; 

CGRect newElementBounds = CGRectApplyAffineTransform(newElementBounds, CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale])); 

[gestureRecognizer视图]应相同元件

回答

2

我想出了一些可以工作的手势处理程序,以便您操作的视图不会偏离您指定的区域。我查看托盘被kscreenEditorSpace定义,2048

泛手势只是调用calcCenterFromXposition:yPosition:fromBoundsInSuperView:方法来设置它的中心,如果中心落在了它只是调整范围,并保持在边界

元素
//-------------------------------------------------------------------------------------------------------- 
// handlePanGesture 
// Description: Called when scrollView got a DoubleFinger DoubleTap Gesture 
//     We want to Zoom out one ZOOM_STEP.    
// 
//-------------------------------------------------------------------------------------------------------- 
- (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer { 

    UIView *element = [gestureRecognizer view]; 


    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) { 
      [[self superview] bringSubviewToFront:self]; 
    } 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { 
      //Front and Center Mr Element! 

      // Find out where we are going 
     CGPoint translation = [gestureRecognizer translationInView:[element superview]]; 
     CGRect elementBoundsInSuperView = [element convertRect:element.bounds toView:[element superview]]; 
     CGFloat xPosition = CGRectGetMidX(elementBoundsInSuperView) + translation.x; 
     CGFloat yPosition = CGRectGetMidY(elementBoundsInSuperView) + translation.y; 

     CGPoint newCenter = [self calcCenterFromXposition:xPosition yPosition:yPosition fromBoundsInSuperView:elementBoundsInSuperView]; 

      //Re position ourselves 
     [element setCenter:newCenter]; 

      //set the translation back to 0 point 
     [gestureRecognizer setTranslation:CGPointZero inView:[element superview]]; 
     [self setNeedsDisplay]; 
    } 

    if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) { 
    } 

} 

所以手柄捏和旋转很漂亮相似。我们不是直接调用Calc Center,而是调用另一种方法来帮助确定我们是否处于边界。

//-------------------------------------------------------------------------------------------------------- 
// handlePinchGesture 
// Description: Called when scrollView got a DoubleFinger DoubleTap Gesture 
//     We want to Zoom out one ZOOM_STEP.    
// 
//-------------------------------------------------------------------------------------------------------- 

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer { 
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) { 

     [[self superview] bringSubviewToFront:self]; 
    } 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { 



     BOOL aSelectedElementOffscreen = FALSE; 
      if ([[gestureRecognizer view] pinchOffScreen:[gestureRecognizer scale]]) { 
       aSelectedElementOffscreen = TRUE; 
      } 

     if (!aSelectedElementOffscreen) { 

      [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]); 

       //Update ourself 
      [self contentSizeChanged]; 
    } 
      [gestureRecognizer setScale:1]; 
    } 

    if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) { 

     if (![self becomeFirstResponder]) { 
      NSLog(@" %@ - %@ - couldn't become first responder", INTERFACENAME, NSStringFromSelector(_cmd)); 
      return; 
     } 
    } 
} 
} 

夹断屏蔽方法

//-------------------------------------------------------------------------------------------------------- 
// pinchOffScreen 
// Description: Called to see if the Pinch Gesture will cause element to go off screen Gesture 
// 
//-------------------------------------------------------------------------------------------------------- 

- (BOOL)pinchOffScreen:(CGFloat)scale { 

    // Save Our Current Transform incase we go off Screen 
CGAffineTransform elementOrigTransform = [self transform]; 
    //Apply our Transform 
self.transform = CGAffineTransformScale([self transform], scale, scale); 
    // Get our new Bounds in the SuperView 
CGRect newElementBoundsInSuperView = [self convertRect:self.bounds toView:[self superview]]; 

    //Find out where we are in the SuperView 
CGFloat xPosition = CGRectGetMidX(newElementBoundsInSuperView); 
CGFloat yPosition = CGRectGetMidY(newElementBoundsInSuperView); 

    //See if we are off the Screen 
BOOL offScreen = [self calcOffEditorFromXposition:xPosition yPosition:yPosition fromBoundsInSuperView: newElementBoundsInSuperView]; 

    // We just wanted to Check. Revert to where we were 
self.transform = elementOrigTransform; 
return offScreen; 

} 

把手旋转是捏类似,我们有一个辅助方法,看看我们是否旋转关闭屏幕。

//-------------------------------------------------------------------------------------------------------- 
// handleRotationGesture 
// Description: Called when we get a rotation gesture 
//     toggle the scroll/zoom lock 
// 
//-------------------------------------------------------------------------------------------------------- 

- (void) handleRotationGesture:(UIRotationGestureRecognizer *)gestureRecognizer{ 
    UIView *element = [gestureRecognizer view]; 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) { 
       [[self superview] bringSubviewToFront:self]; 
    } 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { 


     BOOL aSelectedElementOffscreen = FALSE; 
      if ([element rotateOffScreen:[gestureRecognizer rotation]]) { 
       aSelectedElementOffscreen = TRUE; 
      } 

     if (!aSelectedElementOffscreen) { 

      [gestureRecognizer view].transform = CGAffineTransformRotate([element transform], [gestureRecognizer rotation]); 


       //Update ourself 
      [self contentSizeChanged]; 

     } 
     [gestureRecognizer setRotation:0]; 
    } 
    if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) { 
    } 
} 
} 

旋转关闭屏幕的方法

//-------------------------------------------------------------------------------------------------------- 
// rotateOffScreen 
// Description: Called to see if the Rotation Gesture will cause element to go off screen Gesture 
// 
//-------------------------------------------------------------------------------------------------------- 

- (BOOL)rotateOffScreen:(CGFloat)rotation { 

    // Save Our Current Transform incase we go off Screen 
CGAffineTransform elementOrigTransform = [self transform]; 
    //Apply our Transform 
self.transform = CGAffineTransformRotate([self transform], rotation); 
    // Get our new Bounds in the SuperView 
CGRect newElementBoundsInSuperView = [self convertRect:self.bounds toView:[self superview]]; 

    //Find out where we are in the SuperVire 
CGFloat xPosition = CGRectGetMidX(newElementBoundsInSuperView); 
CGFloat yPosition = CGRectGetMidY(newElementBoundsInSuperView); 

    //See if we are off the Screen 
BOOL offScreen = [self calcOffEditorFromXposition:xPosition yPosition:yPosition fromBoundsInSuperView: newElementBoundsInSuperView]; 

    // We just wanted to Check. Revert to where we were 
self.transform = elementOrigTransform; 

return offScreen; 

} 

计算器屏幕定位辅助方法

#pragma mark - 
#pragma mark === Calc Screen Positioning === 
#pragma mark 
//-------------------------------------------------------------------------------------------------------- 
// calcCenterFromXposition: yPosition: fromBoundsInSuperView: 
// Description: calculate the center point in the element's super view from x, y 
// 
//-------------------------------------------------------------------------------------------------------- 
-(CGPoint) calcCenterFromXposition: (CGFloat) xPosition yPosition:(CGFloat) yPosition fromBoundsInSuperView:(CGRect) elementBoundsInSuperView{ 


    // Ge the Height/width based on SuperView Bounds 
CGFloat elementWidth = CGRectGetWidth(elementBoundsInSuperView); 
CGFloat elementHeight = CGRectGetHeight(elementBoundsInSuperView); 

    //Determine our center.x from the new x 
if (xPosition < elementWidth/2) { 
    xPosition = elementWidth/2; 
} else if (xPosition + elementWidth/2 > kscreenEditorSpace) { 
    xPosition = kscreenEditorSpace - elementWidth/2; 
} 
    //Determine our center.y from the new y 
if (yPosition < elementHeight/2) { 
    yPosition = elementHeight/2; 
} else if (yPosition + elementHeight/2 > kscreenEditorSpace) { 
    yPosition = kscreenEditorSpace - elementHeight/2; 
} 
return (CGPointMake(xPosition, yPosition)); 
} 

//-------------------------------------------------------------------------------------------------------- 
// calcOffEditorFromXposition: yPosition: fromBoundsInSuperView: 
// Description: Determine if moving the element to x, y will it be off the editor screen 
// 
//-------------------------------------------------------------------------------------------------------- 
-(BOOL) calcOffEditorFromXposition: (CGFloat) xPosition yPosition:(CGFloat) yPosition fromBoundsInSuperView:(CGRect) elementBoundsInSuperView{ 

BOOL offScreen = NO; 

    // Ge the Height/width based on SuperView Bounds 
CGFloat elementWidth = CGRectGetWidth(elementBoundsInSuperView); 
CGFloat elementHeight = CGRectGetHeight(elementBoundsInSuperView); 

    // Off Screen on Left 
if (xPosition < elementWidth/2) { 
    offScreen = YES; 
} 
    //Off Screen Right 
if (xPosition + elementWidth/2 > kscreenEditorSpace) { 
    offScreen = YES;; 
} 

    // Off Screen Top 
if (yPosition < elementHeight/2) { 
    offScreen = YES; 
} 

    //Off Screen Bottom 
if (yPosition + elementHeight/2 > kscreenEditorSpace) { 
    offScreen = YES; 
} 

return (offScreen); 
}