I want to draw a line between two UILabels when i tap or hold both of them at the same time with code, i have no idea how to do this, it will be most appreciated if anyone has an advice , it will be most appreciated
3 Answers
This is how I would do it. My answer is tested btw...
To manage the tappable labels I would create my own label called LabelControl that extends UIControl
. This custom control is going to have a UILabel
(read-only for simplicity) as a subview. By doing this we will be able to add the Target-Action events UIControlEventTouchDown
and UIControlEventTouchUpInside
.
Here is the custom label:
The .h file:
@interface LabelControl : UIControl
@property (nonatomic, retain, readonly) UILabel *theLabel;
@end
The .m file:
@implementation LabelControl
@synthesize theLabel = _theLabel;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_theLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
_theLabel.backgroundColor = [UIColor clearColor];
_theLabel.userInteractionEnabled = NO;
[self addSubview:_theLabel];
}
return self;
}
-(void)dealloc {
[_theLabel release];
[super dealloc];
}
Then for the "line" that you want to draw, I would use a UIView
because that way you could just use it's hidden
property to hide/show the line. Add this code inside your ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.label1 = [[[LabelControl alloc] initWithFrame:CGRectMake(60, 50, 200, 40)] autorelease];
self.label1.theLabel.text = @"Hello";
self.label1.userInteractionEnabled = YES;
self.label1.backgroundColor = [UIColor blueColor];
[self.label1 addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[self.label1 addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.label1];
self.label2 = [[[LabelControl alloc] initWithFrame:CGRectMake(60, 150, 200, 40)] autorelease];
self.label2.theLabel.text = @"World";
self.label2.userInteractionEnabled = YES;
self.label2.backgroundColor = [UIColor purpleColor];
[self.label2 addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[self.label2 addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.label2];
//the position of the line is hard-coded. You will have to modify this yourself
self.theLine = [[UIView alloc] initWithFrame:CGRectMake(60, 120, 200, 3)];
self.theLine.backgroundColor = [UIColor blueColor];
self.theLine.hidden = YES;
[self.view addSubview:self.theLine];
}
-(void)showOrHideLine {
if (self.label1.selected && self.label2.selected) {
NSLog(@"Both are selected");
self.theLine.hidden = NO;
} else {
self.theLine.hidden = YES;
}
}
-(void)touchDown:(id)sender {
//When any of the custom label gets the touch down event set the `selected` property
//to YES. (This property is inherited form `UIControl`
NSLog(@"Touch down");
LabelControl *labelControl = (LabelControl*)sender;
labelControl.selected = YES;
[self showOrHideLine];
}
-(void)touchUp:(id)sender {
//When any of the custom label gets the touch up event set the `selected` property
//to NO. (This property is inherited form `UIControl`
NSLog(@"Touch Up");
LabelControl *labelControl = (LabelControl*)sender;
labelControl.selected = NO;
[self showOrHideLine];
}
Let me know if you have any questions. Hope this helps!

- 6,362
- 4
- 34
- 42
-
@user2434519 is this what you were looking for? – LuisCien Jun 10 '13 at 23:01
I am going to outline it and give you some code (untested) but you have some work to make the full effect work.
Programtically, you could subclass UIButton
. Inside your new subclass, put your touch recognition methods. Call it something like "customUIButton".
From your main view controller, create two instances of your UIButton
and add them as subviews
customUIButton *Label1 = [[customUIButton alloc] init];
[Label1 setTitle:@"Your First Label" forState:UIControlStateNormal];
[Label1 addTarget:self action:@selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Label1];
customUIButton *Label2 = [[customUIButton alloc] init];
[Label2 setTitle:@"Your Second Label" forState:UIControlStateNormal];
[Label2 addTarget:self action:@selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Label1];
When you push the buttons, it will try to call the method "itemClicked". Make that method and receive (id)sender... - (void)itemClicked: (id)sender {
Put some logic in there to indicate that the button is being pushed. You know which button by referring to the sender that was sent.
Also in your view controller, go to the DrawRect method and put in the drawing logic.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 3.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextMoveToPoint(context, Label1.center.x, Label1.center.y);
CGContextAddLineToPoint(context, Label2.center.x, Label2.center.y);
CGContextStrokePath(context);
CGContextRestoreGState(context);
Put this in an "if statement" so that if both buttons have focus, it will be drawn (else skip the drawing code).
How about placing a line in IB using an Image View. Hide the Image View in your viewDidLoad method. Then, whenever the user taps one of the the UILabels, unhide the Image View holding your line. It may be tricky depending on your experience with Objective-C to detect touches on a UILabel. If it is, you can place invisible buttons over each label and that should do the trick for you. For more info about detecting touches on UILabels, check this link: Handling Touch Event in UILabel and hooking it up to an IBAction