为UIView层设置锚点

6
我有一个UIView子类,我想让它能够在其父视图中移动。当用户触摸UIView的某个位置,该位置位于self.bounds内但不在self.center内时,它会“跳跃”,因为我将新位置添加到self.center以实现实际移动。为了避免这种行为,我正在尝试设置一个锚点,使用户可以在其边界内的任何地方抓住和拖动视图。
我的问题是,当我计算新的锚点(如下面的代码所示)时,什么都不会发生,视图位置根本不会改变。另一方面,如果我将锚点设置为预先计算的点,我就可以移动视图(但当然它会“跳跃”到预先计算的点)。为什么这不能按预期工作?
谢谢。
- (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;
}

1
请确保您完全理解 anchorPoint 的含义:https://dev59.com/Q3I-5IYBdhLWcg3wNle1#22188420 - 2cupsOfTech
2个回答

13

正如Kris Van Bael所指出的那样,为了不抵消移动,您需要在touchsBegan:withEvent:方法中进行锚点计算。此外,由于更改图层的anchorPoint会移动视图的初始位置,因此您必须将偏移量添加到视图的center点中,以避免第一次触摸后出现“跳跃”。

您可以通过计算(并添加到视图的center点)基于初始和最终锚点之间差异的偏移量(乘以视图的宽度/高度),或者您可以将视图的center设置为初始触摸点。

也许可以这样做:

- (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;
}

关于anchorPoint的更多信息可参考苹果文档此处,我参考的一个类似的Stack Overflow问题请看这里


0

你应该只在TouchBegin时更新锚点。如果你一直重新计算它(TouchMoved),那么子视图不移动是很合理的。


谢谢,当然你是正确的!此外,显然没必要在实际移动开始时重新计算锚点,因为用户不会在范围内移动手指。 但是,将anchorPoint的更新更改为touchesBegan确实引起了偏移问题,正如Sam在他的回答中所指出的那样。 - Oskar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接