I need to draw a horizontal line in a UIView. What is the easiest way to do it. For example, I want to draw a black horizontal line at y-coord=200.
I am NOT using Interface Builder.
I need to draw a horizontal line in a UIView. What is the easiest way to do it. For example, I want to draw a black horizontal line at y-coord=200.
I am NOT using Interface Builder.
Maybe this is a bit late, but I want to add that there is a better way. Using UIView is simple, but relatively slow. This method overrides how the view draws itself and is faster:
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); // Draw them with a 2.0 stroke width so they are a bit more visible. CGContextSetLineWidth(context, 2.0f); CGContextMoveToPoint(context, 0.0f, 0.0f); //start at this point CGContextAddLineToPoint(context, 20.0f, 20.0f); //draw to this point // and now draw the Path! CGContextStrokePath(context); } CGContextBeginPath(context); before CGContextMoveToPoint(...);?The easiest way in your case (horizontal line) is to add a subview with black background color and frame [0, 200, 320, 1].
Code sample (I hope there are no errors - I wrote it without Xcode):
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)]; lineView.backgroundColor = [UIColor blackColor]; [self.view addSubview:lineView]; [lineView release]; // You might also keep a reference to this view // if you are about to change its coordinates. // Just create a member and a property for this... Another way is to create a class that will draw a line in its drawRect method (you can see my code sample for this here).
This is how you can draw a gray line at the end of your view (same idea as b123400's answer)
class CustomView: UIView { override func draw(_ rect: CGRect) { super.draw(rect) if let context = UIGraphicsGetCurrentContext() { context.setStrokeColor(UIColor.gray.cgColor) context.setLineWidth(1) context.move(to: CGPoint(x: 0, y: bounds.height)) context.addLine(to: CGPoint(x: bounds.width, y: bounds.height)) context.strokePath() } } } You can user UIBezierPath Class for this:
And can draw as many lines as you want:
I have subclassed UIView :
@interface MyLineDrawingView() { NSMutableArray *pathArray; NSMutableDictionary *dict_path; CGPoint startPoint, endPoint; } @property (nonatomic,retain) UIBezierPath *myPath; @end And initialized the pathArray and dictPAth objects which will be used for line drawing. I am writing the main portion of the code from my own project:
- (void)drawRect:(CGRect)rect { for(NSDictionary *_pathDict in pathArray) { [((UIColor *)[_pathDict valueForKey:@"color"]) setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor) [[_pathDict valueForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; } [[dict_path objectForKey:@"color"] setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor) [[dict_path objectForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; } touchesBegin method :
UITouch *touch = [touches anyObject]; startPoint = [touch locationInView:self]; myPath=[[UIBezierPath alloc]init]; myPath.lineWidth = currentSliderValue*2; dict_path = [[NSMutableDictionary alloc] init]; touchesMoved Method:
UITouch *touch = [touches anyObject]; endPoint = [touch locationInView:self]; [myPath removeAllPoints]; [dict_path removeAllObjects];// remove prev object in dict (this dict is used for current drawing, All past drawings are managed by pathArry) // actual drawing [myPath moveToPoint:startPoint]; [myPath addLineToPoint:endPoint]; [dict_path setValue:myPath forKey:@"path"]; [dict_path setValue:strokeColor forKey:@"color"]; // NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path]; // [pathArray addObject:tempDict]; // [dict_path removeAllObjects]; [self setNeedsDisplay]; touchesEnded Method:
NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path]; [pathArray addObject:tempDict]; [dict_path removeAllObjects]; [self setNeedsDisplay]; Based on Guy Daher's answer.
I try to avoid using ? because it can cause an application crash if the GetCurrentContext() returns nil.
I would do nil check if statement:
class CustomView: UIView { override func draw(_ rect: CGRect) { super.draw(rect) if let context = UIGraphicsGetCurrentContext() { context.setStrokeColor(UIColor.gray.cgColor) context.setLineWidth(1) context.move(to: CGPoint(x: 0, y: bounds.height)) context.addLine(to: CGPoint(x: bounds.width, y: bounds.height)) context.strokePath() } } } if clause is just to unbox from the optional, prefer to use a guard statement instead.