2011-04-04 68 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); 
}