4

I have multiple UIImageView's within a UIView. These UIImageViews have been transformed.

When the gesture is applied to any one of the UIImageView's the overlapping imageViews should get displaced in such a way that the move outside the UIImageView's frame and we get a full view of the image (all of this would be done in an animating manner).

Also please note that the images will have been transformed so I wont be able to use the frame properties.

Right now I'm using CGRectIntersectsRect but its not giving me the desired effect.

Justin Boo
  • 10,132
  • 8
  • 50
  • 71
Nayan Chauhan
  • 542
  • 5
  • 16

2 Answers2

3

After struggling a lot, finally i achieved the desired result with this algorithm.

  • I calculate the list of overlapping UIImageView's and store it in an array. I am using CGRectIntersectsRect for this.

    Note : This will also include the UIImageView on which the gesture was applied (say target ImageView).

  • For each of these overlapping UIImageView, i perform the following steps :

    1) Calculate the angle between the overlapping ImageView and target ImageView. This will give me the direction to shift the Overlapping ImageView.

    2) Now shift the overlapping ImageView by some constant distance(say len), such that it maintains the same angle. Direction should be such that it moves away from the target ImageView.

    3) You can calculate the new x,y co-ordinates using Sin/Cos functions.

    x = start_x + len * cos(angle);
    y = start_y + len * sin(angle);

    NOTE: For ImageViews whose center is less than your target ImageView's center, you will need to subtract the value.

    4) Now shift the overlapping ImageView to the new calculated center.

    5) Continue shifting it until the views do not intersect any more.

  • I am attaching my code. I hope it helps.

    -(void)moveImage:(UIImageView *)viewToMove fromView:(UIImageView *)imageToSendBack
    {

            CGFloat angle = angleBetweenLines(viewToMove.center, imageToSendBack.center);
    
            CGFloat extraSpace = 50;
    
            CGRect oldBounds = viewToMove.bounds;
            CGPoint oldCenter = viewToMove.center;
    
            CGPoint shiftedCenter;
    
            while(CGRectIntersectsRect(viewToMove.frame,imageToSendBack.frame))
            {
                 CGPoint startPoint = viewToMove.center;
    
                shiftedCenter.x = startPoint.x - (extraSpace * cos(angle));
    
                if(imageToSendBack.center.y < viewToMove.center.y)
                    shiftedCenter.y = startPoint.y + extraSpace * sin(angle);
                else
                    shiftedCenter.y = startPoint.y - extraSpace * sin(angle);
    
    
                viewToMove.center = shiftedCenter;
    
            }
            viewToMove.bounds = oldBounds;
            viewToMove.center = oldCenter;
    
            [self moveImageAnimationBegin:viewToMove toNewCenter:shiftedCenter];
        }
    
Nayan Chauhan
  • 542
  • 5
  • 16
0

I didn't try this, but I would do it like this:

After getting the bool from CGRectIntersectsRect, multiply this overlapping UIImageView x and y by the width and height of it.

And since you can't use frame property after changing the transformation, you will need to multiply the width and height by 1.5 for the maximum amount of rotation.

Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.

This might move some view father than other, but you will be certain all views will be moved outside the UIImageView's frame.

If you try it and it doesn't work, post some code and I will help you with it.

EDIT: For views that their x,y less than your UIImageView's x,y you will need to subtract the offset.

Basel
  • 2,368
  • 1
  • 16
  • 21
  • Thanks @iBasel. I din't try it but even this should work it seems so. I achieved the result by using another algorithm. Have posted it below as well along with the code. – Nayan Chauhan May 17 '12 at 10:37