Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
372 views
in Technique[技术] by (71.8m points)

iphone - Draw Line with gesture

I add a view as sub view using the following code

    imageview = [[UIImageView alloc] initWithFrame:[holderView frame]];
    [imageview setImage:cppobject->OutputImage];
    imageview.contentMode = UIViewContentModeScaleAspectFit;

    [holderView addSubview:imageview];
    holderView.contentMode = UIViewContentModeScaleAspectFit ;

    UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
    [pinchRecognizer setDelegate:self];
    [holderView addGestureRecognizer:pinchRecognizer];
    [pinchRecognizer release];

    UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
    [rotationRecognizer setDelegate:self];
    [holderView addGestureRecognizer:rotationRecognizer];
    [rotationRecognizer release];

    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
    [panRecognizer setMinimumNumberOfTouches:1];
    [panRecognizer setMaximumNumberOfTouches:1];
    [panRecognizer setDelegate:self];
    [holderView addGestureRecognizer:panRecognizer];
    [panRecognizer release];

-(void)scale:(id)sender {
}

-(void)rotate:(id)sender {
}

-(void)move:(id)sender {
}

-(void)tapped:(id)sender {
}

I need to draw line when the user use his two fingers to pan and a uilabel (the green one) like in the following image

I had look on How to draw graphics in iphone gesture?

But I couldn't apply it on the subview , specially the DrawInRect method

in panRecognizer function (move) I want to draw line using

    UIPanGestureRecognizer *gR = (UIPanGestureRecognizer *) sender ; 
    NSValue *value = [NSValue valueWithCGPoint: [gR locationInView:gR.view]]; 
    [Points addObject:value];
    [holderView setNeedsDisplay];

    NSLog(@"End of measuring") ; 

and I will use the points in Points to draw line above all the subviews in

-(void)drawRect:(CGRect)rect { 
  NSLog(@"Entered Draw In Rect");
  if (Measuring) {
    [[UIColor redColor] setStroke];
    UIBezierPath *pathToDraw = [UIBezierPath bezierPath]; 

    for (int n = 1; n < [Points count] - 1 ; n++) { 
      NSValue * value = [Points objectAtIndex:(NSInteger)n];
      CGPoint  point = [value CGPointValue]; 
      [pathToDraw moveToPoint:point];
      value = [Points objectAtIndex:(NSInteger)n+1];
      point = [value CGPointValue];
      [pathToDraw addLineToPoint:point];
    }
    [pathToDraw stroke];
  }
}

the problem is [holderView setNeedsDisplay]; never call or fire drawRect any suggestion or help regarding that

any suggestion

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The image view being the subview draws on top of the holder view. The imageview is opaque. This means that when the views are drawn there is no part of the holder view that is actually visible, so it's drawRect call is optimised out.

Try ordering the views the other way around, so that the holder view is the subview of the imageview. Then the imageview will draw and the holder view will draw on top of it.

Also, note that you should use the bounds of the parent view as the frame of the subview.

UIView* subview = [[UIView alloc] initWithFrame:[parentview bounds]];

Edit (add):

See http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html%23//apple_ref/doc/uid/TP40009503-CH2-SW1 , specifically under the section "View Hierarchies and Subview Management":

"Visually, the content of a subview obscures all or part of the content of its parent view"

So, try make the imageview the parent, do your initialisation like so:

// instance variables:
UIImageView* imageView;
MyHolderView* holderView;

imageView = [[UIImageView alloc] initWithFrame:mainRect];
holderView = [[MyHolderView alloc] initWithFrame:[imageView bounds]];
holderView.opaque = NO;
holderView.backgroundColor = [UIColor clearColor];
[imageView addSubview:holderView];

UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:holderView action:@selector(scale:)];
[pinchRecognizer setDelegate:self];
[holderView addGestureRecognizer:pinchRecognizer];
[pinchRecognizer release];

// etc...

Now, the image view is drawn, and the holder view, its subview is drawn on top of it. Now when you call setNeedsDisplay on the holderview it will receive a drawRect: call.

For example, track the gesture like so. This could be in your view controller or in your MyHolderView view subclass; the example here would be in the MyHolderView class so that the location1 and location2 instance variables can be shared easily with the drawRect: method.:

-(void)scale:(id)sender {
  if (sender == pinchRecognizer) { // this allows the responder to work with multiple gestures if required
    // get position of touches, for example:
    NSUInteger num_touches = [pinchRecognizer numberOfTouches];

    // save locations to some instance variables, like `CGPoint location1, location2;`
    if (num_touches >= 1) {
      location1 = [pinchRecognizer locationOfTouch:0 inView:holderView];
    }
    if (num_touches >= 2) {
      location2 = [pinchRecognizer locationOfTouch:1 inView:holderView];
    }

    // tell the view to redraw.
    [holderView setNeedsDisplay];
  }
}

and then in the holder view drawRect routine:

-(void)drawRect:(CGRect)rect {

  // use instance variables location1 and location2 to draw the line.
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...