简体   繁体   English

如何将手势识别器添加到uibezierpath绘制的形状中

[英]How to add a gesture recognizer to a shape drawn by uibezierpath

I am drawing a circle in the drawRect function in a subclass of UIView 我正在UIView的子类中的drawRect函数中绘制一个圆

- (void)drawRect:(CGRect)rect
{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();  
    CGContextSetLineWidth(contextRef, 2.0);
    CGContextSetRGBFillColor(contextRef, 0, 0, 1.0, 1.0);
    CGContextSetRGBStrokeColor(contextRef, 0, 0, 1.0, 1.0);
    CGRect circlePoint = (CGRectMake(self.bounds.size.width/3, self.bounds.size.height/2, 200.0, 200.0));

    CGContextFillEllipseInRect(contextRef, circlePoint);
}

I want to add a gesture recognizer to the circle to make it tappable 我想在圆圈中添加一个手势识别器,使其可以播放

UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
                                        action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];

I thought of dragging a UIGestureRecognizer onto the view (in storyboard) in the location where the big circle will be, but the circle is much bigger than the UIGestureRecognizer widget. 我想过将UIGestureRecognizer拖到大圆圈所在位置的视图(在故事板中),但圆圈比UIGestureRecognizer小部件大得多。

How can I either combine the code or assign a UIGestureRecognizer to an area of the view that's exactly the same as the size and location of the circle? 如何组合代码或将UIGestureRecognizer分配给视图的区域,该区域与圆的大小和位置完全相同?

The short answer is that you can't. 简短的回答是,你做不到。 Gesture recognizers are attached to views, not shapes or layers. 手势识别器附加到视图,而不是形状或层。 You would have to create a custom view object for each shape. 您必须为每个形状创建自定义视图对象。 You could certainly do that. 你当然可以这样做。

What I suggest you do is to create a custom subclass of UIView that manages all your shapes. 我建议你做的是创建一个UIView的自定义子类来管理你的所有形状。 (I'll call it ShapesView) Have that custom ShapesView manage an array of custom shape objects. (我将其称为ShapesView)让自定义ShapesView管理自定义形状对象的数组。 Attach a gesture recognizer to your ShapesView. 将手势识别器附加到ShapesView。 In the code that responds to gestures, have it do custom hit testing to determine which shape was tapped, and move the shapes around. 在响应手势的代码中,让它进行自定义命中测试以确定敲击哪个形状,并移动形状。

UIBezierPath includes a containsPoint method that would allow you to do hit testing if you maintained a bezier path for each shape. UIBezierPath包含一个containsPoint方法,如果您为每个形状维护bezier路径,则允许您进行命中测试。

I'm not sure how to do it using drawRect the way you are, but I've done something similar using UIBezierPath. 我不确定如何使用drawRect以你的方式做到这一点,但我已经使用UIBezierPath做了类似的事情。 I subclassed UIView, and made this view the main view of my controller. 我将UIView子类化,并将此视图作为我的控制器的主视图。 This is the code in that view, 这是该视图中的代码,

- (id)initWithCoder:(NSCoder *)aDecoder {

     if (self = [super initWithCoder:aDecoder]) {
         self.shape = [UIBezierPath bezierPathWithOvalInRect:(CGRectMake(self.bounds.size.width/3, self.bounds.size.height/3, 200.0, 200.0))];
        }
     return self;
}

-(void)drawRect:(CGRect)rect {
    [[UIColor blueColor] setFill];
    [self.shape fill];
}

shape is a property declared in the .h file. shape是.h文件中声明的属性。 In the view controller .m file, I add the gesture recognizer, and check if the touch is inside the shape, 在视图控制器.m文件中,我添加了手势识别器,并检查触摸是否在形状内,

@interface ViewController ()
@property (strong,nonatomic) RDView *mainView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.mainView = (RDView *)self.view;
    UITapGestureRecognizer *singleFingerTap =
    [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
    [self.view addGestureRecognizer:singleFingerTap];
}

-(void)handleSingleTap:(UITapGestureRecognizer *) tapper {
    if ([self.mainView.shape containsPoint:[tapper locationInView:self.mainView]]) {
        NSLog(@"tapped");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM