【问题标题】:UIBezierPath Path Shape Clickble and DraggableUIBezierPath 路径形状可点击和可拖动
【发布时间】:2011-02-09 21:33:43
【问题描述】:

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

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

#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

【问题讨论】:

    标签: iphone cocoa-touch ios uikit core-graphics


    【解决方案1】:

    最好的方法是对贝塞尔路径进行命中测试。这需要访问 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]; 
    }
    

    Edit 用于仅响应路径内事件的自定义视图。

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
        return [[self myPath] containsPoint:point];
    }
    

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

    【讨论】:

    • 这是对我的问题的一个很好的回答。但我发现我需要一些不同的东西。我需要让 sape 像一个物体,这样它就可以被拖到其他形状上。
    • 我认为我需要的是一种具有自定义形状而不是正方形的 UIView。
    • 使用的方法非常相似。创建一个自定义视图并覆盖 pointInside:withEvent:。然后,使用触摸事件在其父视图中移动视图。我将在我的帖子中添加代码,展示如何针对您的情况实施 pointInside:withEvent:。
    猜你喜欢
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2020-08-06
    • 2010-12-31
    • 1970-01-01
    相关资源
    最近更新 更多