Skip to content

@amarkulo /LineNumbersView.m secret
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Line numbers implementation for UITextView
//
// LineNumbersView.m
// ATTest
//
// Created by Amar Kulo on 2012-10-06.
// Copyright (c) 2012 Amar Kulo. All rights reserved.
//
#define DebugLines 0
#define LineHeight 22
#define LeftMargin 8.5
#define RightMargin 15
#define FontName @"SourceCodePro-Regular"
#define FontSize 14
#define Font [UIFont fontWithName:FontName size:FontSize]
#import "LineNumbersView.h"
#import <tgmath.h>
static CGFloat TOPMARGIN = 8;
@interface LineNumbersView ()
@end
@implementation LineNumbersView
@synthesize text;
@synthesize showLineNumbers;
@synthesize editorWidth;
@synthesize contentOffset;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor colorWithRed:0.945 green:0.945 blue:0.945 alpha:1.000]];
[self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
if (showLineNumbers) {
// Draw separator line
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(self.frame.size.width, 0)];
[bezierPath addLineToPoint: CGPointMake(self.frame.size.width, self.frame.size.height)];
[[UIColor colorWithRed:0.573 green:0.573 blue:0.573 alpha:1.000] setStroke];
bezierPath.lineWidth = 0.5;
[bezierPath stroke];
// create context for drawing
CGContextRef context = UIGraphicsGetCurrentContext();
// get array of all lines in editor
NSArray *allLinesInEditor = [text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
// test string for determining actual size of font used
NSString *testLine = @" ";
// calculate size of the string
CGSize testLineSize = [testLine sizeWithFont:[UIFont systemFontOfSize:14]];
// calculate maxWidth of the target frame
CGFloat maxWidth = editorWidth - LeftMargin - RightMargin;
if (DebugLines) {
NSLog(@"Test line size: %@", NSStringFromCGSize(testLineSize));
NSLog(@"Max width: %f", maxWidth);
}
int lastLineLocation = 0;
for (int i = 0; i < allLinesInEditor.count; i++) {
// retrieve line from array
NSString *line = [allLinesInEditor objectAtIndex:i];
// tab substituion
NSString *newLine = [line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
// calculate line size
CGSize lineSizeFromUIKit = [newLine sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
// storage for line CGRect
CGRect lineRect;
// storage for calculated line height
CGFloat lineHeight = lineSizeFromUIKit.height;
if (i == 0) {
// create rect for first line
lineRect = CGRectMake(0, TOPMARGIN, self.bounds.size.width - 4, 15.084);
} else {
// create rect for new line
lineRect = CGRectMake(0, lastLineLocation, self.bounds.size.width - 4, 15.084);
}
if (line.length == 0) { // empty or new line
// add values to lastLineLocation
lastLineLocation = lineRect.origin.y + testLineSize.height;
} else { // regular line
if (fmod(lineHeight, testLineSize.height) > 0) { // check if there is reminder for line
// calculate number of lines as integer without remainder
int numberOfLines = lineHeight / testLineSize.height;
// then add one line which represents remainder, to number of lines and multiply with line height
lineHeight = (numberOfLines + 1) * testLineSize.height;
}
// add values to lastLineLocation
lastLineLocation = lineRect.origin.y + lineHeight;
}
// substract valule of content offset of editor view
lineRect.origin.y -= contentOffset.y;
if (DebugLines) {
NSLog(@"------------------------------------------------------------------------------------------");
//const char *cString = [line UTF8String];
NSLog(@"Line %i: %@ length: %i", i+1, line.description, line.length);
NSLog(@"Line %i: %@ new line length: %i", i+1, newLine.description, newLine.length);
//NSLog(@"Line %i: %@ char representation: %s", i+1, line, cString);
NSLog(@"Line %i: sizeFromUIKit: %@", i+1, NSStringFromCGSize(lineSizeFromUIKit));
//NSLog(@"Line %i: sizeFromCText: %@", i+1, NSStringFromCGSize(lineSizeFromCoreText));
//NSLog(@"Line %i: sizeFromCharNr: %@", i+1, NSStringFromCGSize(CGSizeMake((line.length * testLineSize.width) / maxWidth, CGFLOAT_MAX)));
NSLog(@"Line %i: number of lines: %f", i+1, lineHeight / testLineSize.height);
NSLog(@"Line %i: new last line location - %d", i+1, lastLineLocation);
}
// drawing
// line background color
CGContextSetFillColorWithColor(context,[UIColor colorWithRed:0.573 green:0.573 blue:0.573 alpha:1.000].CGColor);
// draw line number
[[NSString stringWithFormat:@"%i", i+1] drawInRect:lineRect withFont:[UIFont systemFontOfSize:14] lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentRight];
}
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.