2

I want to do a similar thing to what the app Scalar did, where they made a capability to drag from a point onto the notepad to paste the number to the location they draged the dot too. What I'm really interested in is the line that stays connected to the dot and your finger as shown here:

enter image description here

My problem is that I don't really know what this is called, so I am having trouble searching for how I would do this. Does anyone know what this would be called, have any tutorials they have came across on this subject? And even better if you have some code for me to look at would be awesome.

Thanks.

Craig
  • 1,065
  • 3
  • 12
  • 26
  • 3
    You can probably accomplish the same thing with CGContext drawing http://developer.apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/CGContext/Reference/reference.html. I don't think there are any tutorials on this specific subject; it's something you'd have to code on your own. Depending on your experience this may be difficult. – Dustin Aug 07 '12 at 12:17

3 Answers3

1

It will involving subclassing UIView and implemeting the touchesBegan and touchesMoved method and drawing a line in your view subclass drawRect method from the initial touch to your current touch.

heres a previous question that will help How do I draw a line on the iPhone?

you will just need to change the following so that the coordinates are those of your initial touch and current touch that you obtain from the touches methods

CGContextMoveToPoint(c, 5.0f, 5.0f);
CGContextAddLineToPoint(c, 50.0f, 50.0f);

then calling [self setNeedsDisplay]; in the touchesMoved method will redraw the line to follow your finger as you move.

Then implement touchesEnded for code when the finger is lifted off.

Hoope it helps!

Community
  • 1
  • 1
EagerMike
  • 2,032
  • 1
  • 24
  • 40
1

This example of a UIView that draws lines when a finger is dragged on it and detects the first view to be touched should help you start.

//this goes in the header file called "UILineView.h"

#import <UIKit/UIKit.h>

@interface UILineView : UIView

@end

//this in the implementation file called "UILineView.m"

#import "UILineView.h"

@implementation UILineView

{
    CGPoint _originOfTouchPoint; // your fist touch detected in touchesBegan: method
    CGPoint _currentFingerPositionPoint; // the position you have dragged your finger to
    CGFloat _strokeWidth; // the width of the line you wish to draw
    id _touchStartedObject; // the object(UIView) that the first touch was detected on
}

// If you use Interface Builder to design your interface, Objects in a nib file are reconstituted and then initialized using
// their initWithCoder: method
- (id)initWithCoder:(NSCoder *)decoder
{
    self = [super initWithCoder:decoder];
    if (self) {
        // Initialization code
        _originOfTouchPoint = CGPointMake( 0.0, 0.0 );
        _currentFingerPositionPoint = CGPointMake( 100.0, 100.0 );
        _strokeWidth = 2.0;
    }
    return self;
}
/*
// Use initWithFrame if you are not loding the UIView from a nib file
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        _originOfTouchPoint = CGPointMake( 0.0, 0.0 );
        _currentFingerPositionPoint = CGPointMake( 100.0, 100.0 );
        _strokeWidth = 2.0;
    }
    return self;
}
*/

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    CGContextRef context    = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor( context, [UIColor blueColor].CGColor );
    CGContextSetLineWidth( context, _strokeWidth );
    // fisrt point of line
    CGContextMoveToPoint( context, _originOfTouchPoint.x, _originOfTouchPoint.y );
    // last point of line
    CGContextAddLineToPoint( context, _currentFingerPositionPoint.x, _currentFingerPositionPoint.y );
    // draw the line
    CGContextStrokePath( context );
}

#pragma mark touches

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // get starting point and first view touched (if you need to send that view messages)
    _originOfTouchPoint = [[touches anyObject] locationInView:self];
    _touchStartedObject = [[touches anyObject] view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint movedToPoint = [[touches anyObject] locationInView:self];
    // if moved to a new point redraw the line 
    if ( CGPointEqualToPoint( movedToPoint, _currentFingerPositionPoint ) == NO )
    {
        _currentFingerPositionPoint = movedToPoint;
        // calls drawRect: method to show updated line
        [self setNeedsDisplay];
    }
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // reset values
    _originOfTouchPoint = CGPointZero;
    _currentFingerPositionPoint = CGPointZero;
    _touchStartedObject = nil;
}

@end
Ivan Andriollo
  • 370
  • 1
  • 5
  • question: what would I do if I wanted to restrain it to only work if I clicked in a certain location, or clicked a button? – Craig Aug 07 '12 at 18:10
  • You could read the _touchStartedObject in touchesBegun: and if it is the object you want it to be (UIButton or UIView) you can set a boolean variable to YES. Check that this variable is set to YES in drawRect: – Ivan Andriollo Aug 07 '12 at 18:18
  • `- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // get starting point and first view touched (if you need to send that view messages) _originOfTouchPoint = [[touches anyObject] locationInView:self]; _touchStartedObject = [[touches anyObject] view]; if ( [_touchStartedObject isEqual:someUIButtonOrView] ) { _shouldDrawLine = YES; } }` – Ivan Andriollo Aug 07 '12 at 18:29
  • `- (void)drawRect:(CGRect)rect { if ( _shouldDrawLine ) { //.......... } }` – Ivan Andriollo Aug 07 '12 at 18:30
  • my only problem is that I can't use a button with the UIView. It has to be on a UIViewController, and I can't figure out a way to do this same code in a ViewController. – Craig Aug 07 '12 at 18:53
0

A UIGestureRecognizer can do this without confusing the touch and drag logic with a view. I have used them for editing shapes on maps, long press dragging, etc. See this tutorial.

Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101