Question

Suddenly having remembered this evening a tutorial I read long time ago; it was about scaling a view manually in the UIResponder delegate methods, so I thought I would repeat that from memory for fun.

The tutorial applied CAffineTransformMakeScale as far as my memory serves and I thought I would do this without it and make use of only the bounds of the view I am trying to scale.

What I would like to achieve:

1.) Scale the view with pinch (not making use of CGAffineTransformMakeScale). The scaling should take place from the "middle" of the view not from a corner of it.

2.) prevent the view from being scale when the derived scale value is < 0.0f.

3.) prevent the view from being scaled too big lying outside of its parent's frame.

I quickly came up with the following, which doesn't work, however:

myView = [[UIView alloc] initWithFrame:(CGRect){{0, 0}, 150, 150}];
myView.center = (CGPoint){CGRectGetWidth(self.view.frame)/2, CGRectGetHeight(self.view.frame)/2};
CGPoint initialDistance;
CGPoint endDistance;
CGFloat delta;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if([touches count] > 1)
    {
        initialDistance = (CGPoint){[[[touches allObjects] objectAtIndex:0] locationInView:self.view].x - [[[touches allObjects] objectAtIndex:1] locationInView:self.view].x,
        [[[touches allObjects] objectAtIndex:0] locationInView:self.view].y - [[[touches allObjects] objectAtIndex:1] locationInView:self.view].y};
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if([touches count] > 1)
    {    
        endDistance = (CGPoint){[[[touches allObjects] objectAtIndex:0] locationInView:self.view].x - [[[touches allObjects] objectAtIndex:1] locationInView:self.view].x,
        [[[touches allObjects] objectAtIndex:0] locationInView:self.view].y - [[[touches allObjects] objectAtIndex:1] locationInView:self.view].y};

        delta = sqrtf(powf((endDistance.x - initialDistance.x), 2) + powf((endDistance.y - initialDistance.y), 2));
        delta = delta * 0.01f;

        myView.bounds = (CGRect){{myView.bounds.origin.x / delta, myView.bounds.origin.y / delta}, myView.bounds.size.width * delta, myView.bounds.size.height * delta};           
    }
}

Here I have not implemented the part I mentioned at first (point 2 and 3) where I want to check if the view is being scaled less than the threshold or when it is being scaled greater than its parent's frame, because I would like to get the scaling part right first.

But the scaling here is not successful (I never saw any scaling, the view would "blink" away). At times it is being scaled to a point I would even get a black screen (without causing crash, however, the App still runs. On rare occasions as I try to scale, I would even get a CALayer bounds contains NaN: [0 0; nan 20] exception <<== first time ever seeing this exception).

I think the problem here is a mathematical one. I have no problem making use of CGAffineTransformMakeScale, which I tried not to use because I would like to try doing the same only making use of bounds.

It caught me; I ended up spending hours googling trying to do this and also trying to find out what caused this CALayer bounds contains NaN: [0 0; nan 20].

Hope someone can shed me some light on this and explain to me in detail what I have done wrong and ways to achieve what I want to do here.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top