iphone - UIBezierPath 路径形状可点击和可拖动

标签 iphone cocoa-touch ios uikit core-graphics

我在 View 中有一个 UIBezierPath 。我想在单击形状时显示警报,但实际发生的情况是,不仅在我单击形状时显示警报,而且当我单击 View 中的任意位置时也会显示警报。

如何更改此代码,以便仅当我在彩色形状内单击时才会收到警报?
另外,如何使形状在屏幕上可拖动?

#import "draw2D.h"
@implementation draw2D

- (id)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];
if (self) {
    // Initialization code.
}
return self;
}

- (void)drawRect:(CGRect)rect {
UIBezierPath*    aPath = [UIBezierPath bezierPath]; 

[aPath moveToPoint:CGPointMake(200.053,79.688)];    
[aPath addLineToPoint:CGPointMake(100.053,179.688)];
[aPath addLineToPoint:CGPointMake(304.412,280.125)];
[aPath addLineToPoint:CGPointMake(308.055,298.513)];
[aPath addLineToPoint:CGPointMake(200.053,79.688)];

[aPath closePath]; 

[[UIColor blackColor] setStroke]; 
[[UIColor redColor] setFill]; 

CGContextRef aRef = UIGraphicsGetCurrentContext(); 
CGContextTranslateCTM(aRef, 50, 50); 
aPath.lineWidth = 5; 
[aPath fill]; 
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Some message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: nil]; 
//After some time 
[alert show]; 
[alert release]; 
}

- (void)dealloc {
[super dealloc];
}

@end

最佳答案

最好的方法是对贝塞尔路径进行 HitTest 。这需要访问 drawRect: 方法之外的路径。由于您的路径始终相同,因此您可以使用静态变量轻松完成此操作。

//add this method to your class
- (UIBezierPath *)myPath {
    static UIBezierPath *path = nil;
    if(!path) {
        path = [[UIBezierPath bezierPath] retain];
        [path moveToPoint:CGPoingMake(200.053,79.688)];
        [path addLineToPoint:CGPointMake(100.053,179.688)];
        [path addLineToPoint:CGPointMake(304.412,280.125)];
        [path addLineToPoint:CGPointMake(308.055,298.513)];
        [path addLineToPoint:CGPointMake(200.053,79.688)];
        [path closePath];
        path.lineWidth = 5;
    }
    return path;
}

- (void)drawRect:(CGRect)rect {
    UIBezierPath*    aPath = [self myPath];

    [[UIColor blackColor] setStroke]; 
    [[UIColor redColor] setFill]; 

    CGContextRef aRef = UIGraphicsGetCurrentContext(); 
    CGContextTranslateCTM(aRef, 50, 50); 
    [aPath fill]; 
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if(![[self myPath] containsPoint:[[touches anyObject] locationInView:self]]) return;

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Some message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: nil]; 
    //After some time 
    [alert show]; 
    [alert release]; 
}

编辑 对于仅响应路径内事件的自定义 View 。
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return [[self myPath] containsPoint:point];
}

使用这种方法,您不需要检查触摸是否在 touchesBegan 的路径内,因为您不应该得到任何会导致测试失败的事件。您可以通过将其框架原点更改为与触摸移动相同的量来移动 View 。

关于iphone - UIBezierPath 路径形状可点击和可拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4950749/

相关文章:

iPhone 垃圾桶吸动画

ios - DispatchQueue优先级和线程分析?

ios - 如何避免 Touches 取消事件?

ios - 核心数据属性的自定义 Getter

ios - 将外部框架连接到 UI 单元测试目标,iOS

iphone - 如何在 iOS 的 post 请求中发送表单数据?

ios - RegisterUserNotificationSettings 是否被调用了两次?

iphone - CoreGraphics 用不同颜色渲染两条或多条线

ios - 使用 CAAnimationGroup 序列化动画

iphone - 保存和加载单个值,iPhone