I have a UIView subclass that I want to be able to move around within it's superview. When the user touches the UIView somewhere outside self.center
but within self.bounds
it "jumps" because I add the new location to self.center
to achieve the actual move. To avoid this behavior I'm trying to set an anchor point that lets the user grab and drag the view anywhere within it's bounds.
My problem is that when I calculate the new anchor point (as shown in the code below) nothing happens, the view doesn't change position at all. On the other hand, if I set the anchor point to a precalculated point I can move the view (but then of course it "jumps" to the precalculated point). How come this doesn't work as expected?
Thanks.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// Only support single touches, anyObject retrieves only one touch
UITouch *touch = [touches anyObject];
CGPoint locationInView = [touch locationInView:self];
// New location is somewhere within the superview
CGPoint locationInSuperview = [touch locationInView:self.superview];
// Set an anchorpoint that acts as starting point for the move
// Doesn't work!
self.layer.anchorPoint = CGPointMake(locationInView.x / self.bounds.size.width, locationInView.y / self.bounds.size.height);
// Does work!
self.layer.anchorPoint = CGPointMake(0.01, 0.0181818);
// Move to new location
self.center = locationInSuperview;
}
As Kris Van Bael pointed out, your going to need to do the anchor point calculations in the touchsBegan:withEvent:
method in order not to negate the movement. Additionally, since changing the layer's anchorPoint
will move the view's initial position, you have to add an offset to the view's center
point to avoid a 'jump' after the first touch.
You can do this by calculating (and adding to your view's center
point) the offset based on the difference between the initial and final anchorPoints (multiplied by your view's width/height) or you could set the view's center
to the initial touch point.
Something like this perhaps:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationInView = [touch locationInView:self];
CGPoint locationInSuperview = [touch locationInView:self.superview];
self.layer.anchorPoint = CGPointMake(locationInView.x / self.frame.size.width, locationInView.y / self.frame.size.height);
self.center = locationInSuperview;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint locationInSuperview = [touch locationInView:self.superview];
self.center = locationInSuperview;
}
More info on anchorPoint
's from apple's docs here and a similar SO question I referenced here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With