【问题标题】:Draw arrow with pan using objective c使用物镜 c 用平底锅绘制箭头
【发布时间】:2015-09-09 00:08:06
【问题描述】:

我的工作:

我一直在尝试向应用程序添加箭头,但最困难的是让它完成它需要做的事情。箭头需要从由手指触摸表示的起点绘制,并在用户在屏幕上拖动手指时增大箭头。然后箭头必须在手指抬起时停止绘制。

我遇到的问题:

当用户触摸箭头任一端的点并沿一个方向拖动手指时,箭头必须能够围绕起点和终点旋转。旋转时,箭头必须能够增大和减小它的大小。

我可以让箭头围绕起点旋转,但有问题。围绕终点旋转会导致“鱼尾”效果。我很确定我这样做的方式是完全错误的,但我不知道任何其他方式。这就是为什么要求社区引导我朝着正确的方向前进。

@implementation ViewController {
ArrowView *_selectedArrowView;
UIColor *_selectedColor;
CGFloat _selectedWeight;
CGFloat _initalAngle;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    _selectedColor = [UIColor yellowColor];
    _selectedWeight = 3;

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)];
    [self.view addGestureRecognizer:pan];

    _selectedArrowView = [[ArrowView alloc] initWithFrame:CGRectMake(300, 300, 150, 25) withColor:_selectedColor withWeight:_selectedWeight withStartPoint:CGPointMake(300, 300) withEndPoint:CGPointMake(450, 300)];
    _selectedArrowView.delegate = self;
    _selectedArrowView.layer.anchorPoint = CGPointMake(0, 0);
    _selectedArrowView.layer.position = CGPointMake(150,300);
    [self.view addSubview:_selectedArrowView];
    [self.view bringSubviewToFront:_selectedArrowView];
}

- (void) panHandler: (UIPanGestureRecognizer *) sender {
    CGPoint touchPoint = [sender locationInView:sender.view];

    if (sender.state == UIGestureRecognizerStateBegan) {
        _initalAngle = atan2(touchPoint.y, touchPoint.x);
    } else if (sender.state == UIGestureRecognizerStateChanged) {
        CGFloat currentAngle = atan2(touchPoint.y, touchPoint.x);
        CGFloat angle = _initalAngle - currentAngle;
        CGAffineTransform transform = CGAffineTransformMakeRotation(angle * -1);
        _selectedArrowView.transform = transform;
    }
}

@end

Link to code on GitHub

【问题讨论】:

  • “一个与 Skitch 应用中的箭头功能相同的箭头”你能描述一下这是什么意思吗?
  • 箭头需要做到以下几点: 1. 用手指运动在屏幕上绘图。 (我得到了这个工作。) 2. 以箭头的起点或终点为轴心点在 360 度圆中平移。 (我无法正确使用它。)我以 Skitch 为例,因为它比描述更容易看到。
  • 所以你误用了“pan”这个词?你真的只是指旋转?
  • 是的,围绕箭头起源的中心点将箭头旋转 360 度圈,同时能够增加起点和起点的大小。
  • 很抱歉,您一直在更改“规格”。这是您第一次提到“同时能够增加尺寸”。这使得问题是什么变得非常不清楚,并且无法提供帮助。请停下来想想你到底想要什么。然后编辑您的问题以清楚地描述您遇到的问题,并显示您到目前为止的代码。

标签: ios objective-c transform skitch


【解决方案1】:

我认为您实际遇到的问题的核心是(来自您的评论):

如果用户选择一端并在屏幕上移动手指,则箭头应围绕用户触摸的另一端旋转,并调整箭头的长度。

让我们假设箭头实际上是一个在自身内部绘制箭头的视图。所以这实际上是关于拉伸和旋转视图。现在让我们处理旋转部分。显然,这将通过应用“跟随”用户触摸的旋转变换来实现。这里要理解的是,一个视图实际上是一个层,一个层围绕它的anchorPoint旋转。

因此,当用户第一次触摸视图时,您必须查看触摸在视图中的位置,并确定这是哪一端。然后,您必须将anchorPoint 移动到 other 端,这样当我们随后旋转时,您将围绕另一端旋转。但是,更改 anchorPoint 会导致视图跳转,除非您还更改图层的 position 以进行补偿,因此您也将这样做。

我们现在已经安全地将anchorPoint 移动到用户手指对面的一端。现在我们只需要在手势继续时围绕它旋转以跟随用户的手指。您将通过将触摸坐标从笛卡尔坐标转换为极坐标来完成此操作,从而给出要应用的角度。在手势开始时,保存 initial 角度;随着手势的继续,从当前角度减去该角度,并使用产生的差异角度将 transform 设置为旋转变换。

这通常有助于简化问题。在这个例子中,我没有跟随手指 - 只是制作动画。如您所见,我可以轻松地绕箭头的一端旋转,然后绕另一端旋转,然后再绕第一端旋转,以此类推。这实际上显示了在应用旋转变换之前移动anchorPointposition 的效果。我建议您先解决问题的这个简单方面,然后再担心跟随用户的手指。

【讨论】:

  • 我已经实现了上面的,但它最多只能旋转30度左右。我确定我只是一些小东西。我已编辑问题以包含已实现的代码。我保持简单,只处理试图让一个点旋转。
  • 您必须计算角度(极坐标)相对于要旋转的锚点。 - 它可能会帮助您查看一些实际工作的代码:apeth.com/iOSBook/ch25.html#_custom_controls 好的,我正在围绕视图中心旋转,而不是视图的远端,但原理完全相同。
  • 谢谢先生。我非常感谢帮助。我现在可以围绕两端旋转箭头。现在,当我将箭头从 45 度角重新定位到 135 度角时,另一端跳到 Y 位置。这是有道理的,因为锚点发生了变化。现在我要去寻找这个问题的解决方案。我还命令您预订“Programming iOS 8”,因为我显然需要它。再次感谢。
  • “当我将箭头从 45 度角重新定位到 135 度角时,另一端跳到 Y 位置。这是有道理的,因为锚点发生了变化”我认为这会当我说您需要更改position 时,请注意当您更改anchorPoint 时,但显然不是 - 听起来旋转变换也必须更改以进行补偿,这是我没有想到的。很抱歉!
  • 你知道如何改变它的好例子吗?我尝试使用 CGAffineTransformTranslate,但我不应该使用该事件。我也尝试过改变箭头层本身,但也没有成功。
猜你喜欢
  • 2015-01-03
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多