【问题标题】:Setting anchor point for UIView layer为 UIView 层设置锚点
【发布时间】:2011-06-16 21:15:39
【问题描述】:

我有一个 UIView 子类,我希望它能够在它的超级视图中移动。当用户在self.center 之外但在self.bounds 内触摸 UIView 时,它会“跳跃”,因为我将新位置添加到 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;
}

【问题讨论】:

标签: iphone objective-c uiview


【解决方案1】:

正如 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;
}

苹果文档here 中有关anchorPoint 的更多信息以及我引用的类似SO 问题here

【讨论】:

    【解决方案2】:

    您应该只在 TouchBegin 上更新锚点。如果您一直重新计算它(TouchMoved),那么子视图不移动是合乎逻辑的。

    【讨论】:

    • 谢谢,你当然是对的!此外,重新计算锚点显然没有意义,因为当实际移动开始时用户不会在边界内移动手指。然而,正如 Sam 在他的回答中强调的那样,将 anchorPoint 的更新更改为 touhesBegan 确实会出现偏移问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 2021-02-07
    • 2013-01-26
    • 2018-02-27
    • 1970-01-01
    相关资源
    最近更新 更多