Reputation: 12807
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.
Upvotes: 90
Views: 154630
Reputation: 5350
This is the simplest of all I could find...
let lineView = UIView(frame: CGRect(x: 4, y: 50, width: self.view.frame.width, height: 1))
lineView.backgroundColor = .lightGray
self.view.addSubview(lineView)
Upvotes: 3
Reputation: 5601
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()
}
}
}
Upvotes: 37
Reputation: 19
Add label without text and with background color corresponding frame size(ex:height=1). Do it through code or in interface builder.
Upvotes: -1
Reputation: 19
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()
}
}
}
Upvotes: 1
Reputation: 14235
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).
Upvotes: 122
Reputation: 6118
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);
}
Upvotes: 313
Reputation: 961
One other (and an even shorter) possibility. If you're inside drawRect, something like the following:
[[UIColor blackColor] setFill];
UIRectFill((CGRect){0,200,rect.size.width,1});
Upvotes: 12
Reputation: 2237
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];
Upvotes: 13
Reputation: 195
Just add a Label without text and with background color. Set the Coordinates of your choice and also height and width. You can do it manually or with Interface Builder.
Upvotes: 15