如何用iphone手势绘制图形?

发布于 2024-11-10 17:18:52 字数 1642 浏览 1 评论 0原文

我有一个问题,如何在用户在 iPhone 上进行平移手势(即用户触摸并拖动手指)后绘制线条或圆形指示器。然而,UIGraphicsGetCurrentContext()总是返回nil,有谁知道如何在iPhone上实现这个?

谢谢, 克鲁

@interface MyView : UIView <UIGestureRecognizerDelegate> {
CGPoint location;
PanIndicator *panIndicator;
}

@implementation MyView 
- (id)init {
    if (self = [super init]) {
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
        [panGesture setMaximumNumberOfTouches:1];
        [panGesture setDelegate:self];
        [self addGestureRecognizer:panGesture];
        [panGesture release];

        panIndicator = [[PanIndicator alloc] init];
        [self addSubview:panIndicator];
    }
    return self;
}

- (void)panAction:(UIPanGestureRecognizer *)gR {
    if ([gR state]==UIGestureRecognizerStateBegan) {
        location = [gR locationInView:self];
    } else if ([gR state]==UIGestureRecognizerStateEnded) {
    //  The following code in this block is useless due to context = nil
//      CGContextRef context = UIGraphicsGetCurrentContext();
//      CGContextAddRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0));
//      CGContextStrokePath(context);
    } else if ([gR state]==UIGestureRecognizerStateChanged) {
    CGPoint location2 = [gR locationInView:self];
        panIndicator.frame = self.bounds;
        panIndicator.startPoint = location;
        panIndicator.endPoint = location2;
//      [panIndicator setNeedsDisplay];    //I don't know why PanIncicator:drawRect doesn't get called
        [panIndicator drawRect:CGRectMake(0, 0, 100, 100)]; //CGRectMake is useless
    }
}

I have a question to draw a line or circle indicator after user has pan gesture (i.e. user touches and drags their finger) on iPhone. However, UIGraphicsGetCurrentContext() always returns nil, does anyone know how to implement this on iPhone?

Thanks,
clu

@interface MyView : UIView <UIGestureRecognizerDelegate> {
CGPoint location;
PanIndicator *panIndicator;
}

@implementation MyView 
- (id)init {
    if (self = [super init]) {
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
        [panGesture setMaximumNumberOfTouches:1];
        [panGesture setDelegate:self];
        [self addGestureRecognizer:panGesture];
        [panGesture release];

        panIndicator = [[PanIndicator alloc] init];
        [self addSubview:panIndicator];
    }
    return self;
}

- (void)panAction:(UIPanGestureRecognizer *)gR {
    if ([gR state]==UIGestureRecognizerStateBegan) {
        location = [gR locationInView:self];
    } else if ([gR state]==UIGestureRecognizerStateEnded) {
    //  The following code in this block is useless due to context = nil
//      CGContextRef context = UIGraphicsGetCurrentContext();
//      CGContextAddRect(context, CGRectMake(30.0, 30.0, 60.0, 60.0));
//      CGContextStrokePath(context);
    } else if ([gR state]==UIGestureRecognizerStateChanged) {
    CGPoint location2 = [gR locationInView:self];
        panIndicator.frame = self.bounds;
        panIndicator.startPoint = location;
        panIndicator.endPoint = location2;
//      [panIndicator setNeedsDisplay];    //I don't know why PanIncicator:drawRect doesn't get called
        [panIndicator drawRect:CGRectMake(0, 0, 100, 100)]; //CGRectMake is useless
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

杀お生予夺 2024-11-17 17:18:52

您应该在应用程序的数据部分中跟踪手指。在 -(void)panAction:(UIPanGestureRecognizer *)gR 中调用 [myCanvasView setNeedsDisplay] 和 myCanvasView -drawInRect:(CGRect)rect 方法绘制这条轨道。

像这样的东西:

- (void)panAction:(UIPanGestureRecognizer *)gR 
{
    [myData addPoint:[gR locationInView:gR.view]];
    [myCanvasView setNeedsDisplay];
}

- (void)drawInRect:(CGRect)rect
{
    [self drawLinesFromData:myData];
}

PanIndicator 草案:

@interface PanIndicator : UIView {}
@property (nonatomic, assign) CGPoint startPoint;
@property (nonatomic, assign) CGPoint endPoint;
@end

@implementation PanIndicator
@synthesize startPoint = startPoint_;
@synthesize endPoint = endPoint_;

- (void)drawRect:(CGRect)aRect 
{
    [[UIColor redColor] setStroke];

    UIBezierPath *pathToDraw = [UIBezierPath bezierPath];
    [pathToDraw moveToPoint:self.startPoint];
    [pathToDraw addLineToPoint:self.endPoint];
    [pathToDraw stroke]
}

@end

You should keep track of the finger in your application's data part. Call [myCanvasView setNeedsDisplay] in -(void)panAction:(UIPanGestureRecognizer *)gR and in myCanvasView -drawInRect:(CGRect)rect method draw this track.

Something like this:

- (void)panAction:(UIPanGestureRecognizer *)gR 
{
    [myData addPoint:[gR locationInView:gR.view]];
    [myCanvasView setNeedsDisplay];
}

- (void)drawInRect:(CGRect)rect
{
    [self drawLinesFromData:myData];
}

A draft for PanIndicator:

@interface PanIndicator : UIView {}
@property (nonatomic, assign) CGPoint startPoint;
@property (nonatomic, assign) CGPoint endPoint;
@end

@implementation PanIndicator
@synthesize startPoint = startPoint_;
@synthesize endPoint = endPoint_;

- (void)drawRect:(CGRect)aRect 
{
    [[UIColor redColor] setStroke];

    UIBezierPath *pathToDraw = [UIBezierPath bezierPath];
    [pathToDraw moveToPoint:self.startPoint];
    [pathToDraw addLineToPoint:self.endPoint];
    [pathToDraw stroke]
}

@end
眼趣 2024-11-17 17:18:52

我用自定义手势做到了这一点。当手势设置手势状态(从触摸开始、移动或结束)时,手势操作回调会在视图中发生,视图调用“setNeedsDisplayInRect”,然后从drawRect进行绘制。

您的实现的问题是您无法从手势的跟踪方法中设置图形上下文。当视图被标记为需要重绘(通过“setNeedsDisplay”)时,这就为您完成了。

这样做的原因是视图的内容可以缓存在图层中,这对于优化动画和合成非常重要。因此,如果您需要在视图中绘制,请通过调用 setNeedsDisplay 并通过 drawRect 方法进行绘制,使界面的其余部分与您的更改保持同步。

I did this with a custom gesture. When the gesture sets the gesture state (from touches began, moved or ended) the gestures action callback occurs back in the view, and the view calls "setNeedsDisplayInRect" and then the drawing occurs from drawRect.

The catch with your implementation is that you do not get to set the graphics context from within the gesture's tracking methods. When a view is flagged as needing redraw (via 'setNeedsDisplay') this is done for you.

The reason for this is so that the view's contents can be cached in a layer, which is really important for optimising animations and compositing. So if you need to draw in a view, keep the rest of the interface in sync with your changes by calling setNeedsDisplay and doing the drawing from your drawRect method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文