Search code examples
iosobjective-cdrawingswiftuigraphicscontext

Drawing lines in Swift


I'm drawing a horizontal line and a vertical line on a UITableViewCell using the following code and it works fine on iOS7. Its in Objective-C.

In the subclass of the,

@property (strong, nonatomic) NSMutableArray *columns;

- (void)drawRect:(CGRect)rect
{
    // In iOS7, you have to set the cell's background color to clear otherwise the drawing lines won't appear
    self.backgroundColor = [UIColor clearColor];

    // Drawing the vertical line
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.5, 1.0);
    CGContextSetLineWidth(ctx, 0.75);
    for (int i = 0; i < self.columns.count; i++) {
        CGFloat f = [((NSNumber*) [self.columns objectAtIndex:i]) floatValue];
        CGContextMoveToPoint(ctx, f, 10);
        CGContextAddLineToPoint(ctx, f, self.bounds.size.height - 10);
    }
    CGContextStrokePath(ctx);

    // Drawing the horizontal line
    CGContextRef cntx = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.5, 1.0);
    CGContextSetLineWidth(cntx, 1);
    for (int i = 0; i < self.columns.count; i++) {
        CGContextMoveToPoint(cntx, 15, self.bounds.size.height / 2);
        CGContextAddLineToPoint(cntx, 60, self.bounds.size.height / 2);
    }
    CGContextStrokePath(cntx);

    [super drawRect:rect];
}

- (void)addColumn:(CGFloat)position
{
    [self.columns addObject:[NSNumber numberWithFloat:position]];
}

And it looks like this,

enter image description here

I'm trying to implement the same in Swift. However those lines don't appear. Here is my code so far,

var columns: [CGFloat] = []

override func drawRect(rect: CGRect)  {

    // Drawing the vertical line
    let ctx = UIGraphicsGetCurrentContext()
    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.5, 1.0)
    CGContextSetLineWidth(ctx, 0.75)
    for var i = 0; i < self.columns.count; i++ {
        let f = self.columns[i] as? float // Error - Use of module 'float' as a type
        CGContextMoveToPoint(ctx, f, 10)
        CGContextAddLineToPoint(ctx, f, self.bounds.size.height - 10)
    }
    CGContextStrokePath(ctx)

    // Drawing the horizontal line
    let cntx = UIGraphicsGetCurrentContext()
    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.5, 1.0)
    CGContextSetLineWidth(cntx, 1)
    for var i = 0; i < self.columns.count; i++ {
        CGContextMoveToPoint(cntx, 15, self.bounds.size.height / 2)
        CGContextAddLineToPoint(cntx, 60, self.bounds.size.height / 2)
    }
    CGContextStrokePath(cntx)

    self.backgroundColor = UIColor.clearColor()

    super.drawRect(rect)
}

func addColumn(position: CGFloat) {
    self.columns.append(NSNumber.numberWithFloat(position)) // Error - 'NSNumber' is not a subtype of 'Float'
}

Multiple errors come up in the first block of the code. The error message is 'AnyObject' is not convertible to 'CGFloat'. No errors in the second block but still the line doesn't appear.

Can someone please tell me what I'm missing here?

Thank you.


Solution

  • Objective-C can only store objects in an NSArray which is why the float value had to be wrapped in a NSNumber. In Swift, this is much easier as you can just store the floats directly. Now that your columns array is of type [CGFloat] you can simply append the value without wrapping it as an NSNumber:

    func addColumn(position: CGFloat) {
      self.columns.append(position)
    }
    

    You don't need to convert the values coming from the columns array because they're already floats:

    for f in self.columns {
      CGContextMoveToPoint(ctx, f, 10)
      CGContextAddLineToPoint(ctx, f, self.bounds.size.height - 10)
    }