How to redraw a certain rect in drawRect - ios

Here is my problem. I am planning to draw 999 circles inside a view at the time of setup, which is done successfully in drawRect. After that, I am planning to edit the color of each circle when user touches (which i am handling using the tap gesture in the view controller). The problem is, when I call [self.pegView setNeedsDisplay]; the drawRect is getting called and goes to the else part of the if in drawRect (which it should), but all the other beads are removed, and I see only 1 bead instead of 999 beads.
Below is my code.
- (void)drawRect:(CGRect)rect
{
if(!self.isEditingHappening) // For the initial setup
{
CGRect beadRect = CGRectMake(BEAD_ORIGIN_X, BEAD_ORIGIN_Y, BEAD_VIEW_SIZE, BEAD_VIEW_SIZE);
self.ctx = UIGraphicsGetCurrentContext();
for(int i = 0 ; i < 999 ; i++)
{
// To set up the bead view for each column
if (i !=0 && i % 37 !=0)
{
beadRect.origin = CGPointMake((beadRect.origin.x + BEAD_VIEW_SIZE), beadRect.origin.y);
}
// To set up bead view for each row
if (i !=0 && i %37 ==0 )
{
beadRect.origin.y += BEAD_VIEW_SIZE;
beadRect.origin = CGPointMake(BEAD_ORIGIN_X, beadRect.origin.y);
}
BeadPattern *pattern = [self.beadPatternsArray objectAtIndex:(i/37)];
int beadType=[[pattern.eachRowPattern objectAtIndex:i%37] intValue];
BeadColor *color=[self.beadColorsArray objectAtIndex:beadType];
CGPoint center;
center.x = beadRect.origin.x + beadRect.size.width / 2.0;
center.y = beadRect.origin.y + beadRect.size.height / 2.0;
CGRect newInnerRect;
newInnerRect.size.width = beadRect.size.width * 0.6;
newInnerRect.size.height = beadRect.size.height * 0.6;
newInnerRect.origin.x = center.x - newInnerRect.size.width/2;
newInnerRect.origin.y = center.y - newInnerRect.size.height/2;
[[UIColor whiteColor] set];
UIRectFill(beadRect);
// Adds the outer circle
CGContextAddEllipseInRect(self.ctx, beadRect);
// Fill the outer circle with any color
CGContextSetRGBFillColor(self.ctx, color.redValue, color.greenValue, color.blueValue, 1);
CGContextFillEllipseInRect(self.ctx, beadRect);
//Add inner circle
CGContextAddEllipseInRect(self.ctx, newInnerRect);
//Fill inner circle with white color
CGContextSetRGBFillColor(self.ctx, 1, 1, 1, 0.4);
CGContextFillEllipseInRect (self.ctx, newInnerRect);
}
}
else // When editing is happening
{
NSLog(#"The redrawing rect is %#", NSStringFromCGRect(rect));
CGContextSaveGState(self.ctx);
CGRect beadRect;
beadRect.size = CGSizeMake(BEAD_VIEW_SIZE, BEAD_VIEW_SIZE);
beadRect.origin = CGPointMake(self.columnToBeUpdated * BEAD_VIEW_SIZE, self.rowToBeUpdated * BEAD_VIEW_SIZE);
CGPoint center;
center.x = beadRect.origin.x + beadRect.size.width / 2.0;
center.y = beadRect.origin.y + beadRect.size.height / 2.0;
CGRect newInnerRect;
newInnerRect.size.width = beadRect.size.width * 0.6;
newInnerRect.size.height = beadRect.size.height * 0.6;
newInnerRect.origin.x = center.x - newInnerRect.size.width/2;
newInnerRect.origin.y = center.y - newInnerRect.size.height/2;
CGContextRestoreGState(self.ctx);
[[UIColor whiteColor] set];
UIRectFill(beadRect);
// Adds the outer circle
CGContextAddEllipseInRect(self.ctx, beadRect);
// Fill the outer circle with any color
CGContextSetRGBFillColor(self.ctx, self.colorToBeShownWhileEdited.redValue, self.colorToBeShownWhileEdited.greenValue, self.colorToBeShownWhileEdited.blueValue, 1);
CGContextFillEllipseInRect(self.ctx, beadRect);
//Add inner circle
CGContextAddEllipseInRect(self.ctx, newInnerRect);
//Fill inner circle with white color
CGContextSetRGBFillColor(self.ctx, 1, 1, 1, 0.4);
CGContextFillEllipseInRect (self.ctx, newInnerRect);
}
}
What I intend to do is, keep all the 999 beads, but edit only one bead's color for which the user has touched. I tries using [setNeedsDisplayInRect] also, but the rect is not passed correctly. Please help me here.

If I remember correctly, it clears off the other items on the canvas -so your initial setup stuff would need to run each time.
Or, you could create separate views for each bead that would allow you to just follow that one specifically. Each bead could contain its own logic.

Related

how do I make the base of each UIView a tangent to a circle so they radiate from the centre?

I am trying to find angles of rotation for a series of light and dark rectangular UIViews placed at regular points on a circle perimeter. Each point on the circle is calculated as an angle of displacement from the centre and I have tried using the same angle to rotate each UIView so it radiates from the centre. But I didn't expect it to look like this.
I expected the angle of displacement from the centre to be the same as the angle of rotation for each new UIView. Is this assumption correct ? and if so, how do I make the base of each UIView a tangent to a circle so they radiate from the centre ?
UPDATE
In case someone finds it useful here is an update of my original code. The problem as explained by rmaddy has been rectified.
I’ve included two versions of the transform statement and their resulting rotated UIViews. Result on the left uses radians + arcStart + M_PI / 2.0, result on right uses radians + arcStart.
Here is the method.
- (void)sprocket
{
CGRect canvas = [UIScreen mainScreen].bounds;
CGPoint circleCentre = CGPointMake((canvas.size.width)/2, (canvas.size.height)/2);
CGFloat width = 26.0f;
CGFloat height = 50.0f;
CGPoint miniViewCentre;
CGFloat circleRadius = 90;
int miniViewCount = 16;
for (int i = 0; i < miniViewCount; i++)
{
// to place the next view calculate angular displacement along an arc
CGFloat circumference = 2 * M_PI;
CGFloat radians = circumference * i / miniViewCount;
CGFloat arcStart = M_PI + 1.25f; // start circle from this point in radians;
miniViewCentre.x = circleCentre.x + circleRadius * cos(radians + arcStart);
miniViewCentre.y = circleCentre.y + circleRadius * sin(radians + arcStart);
CGPoint placeMiniView = CGPointMake(miniViewCentre.x, miniViewCentre.y);
CGRect swivellingFrame = CGRectMake(placeMiniView.x, placeMiniView.y, width, height);
UIView *miniView = [[UIView alloc] initWithFrame:swivellingFrame];
if ((i % 2) == 0)
{
miniView.backgroundColor = [UIColor darkGrayColor];
}
else
{
miniView.backgroundColor = [UIColor grayColor];
}
miniView.layer.borderWidth = 1;
miniView.layer.borderColor = [UIColor blackColor].CGColor;
miniView.layer.cornerRadius = 3;
miniView.clipsToBounds = YES;
miniView.layer.masksToBounds = YES;
miniView.alpha = 1.0;
// using the same angle rotate the view around its centre
miniView.transform = CGAffineTransformRotate(miniView.transform, radians + arcStart + M_PI / 2.0);
[page1 addSubview:miniView];
}
}
The problem is your calculation of the center of each miniView is based on radians plus arcStart but the transform of each miniView is only based on radians.
Also note that angle 0 is at the 3 o'clock position of the circle. You actually want a 90° (or π/2 radians) rotation of miniView so the rectangle "sticks out" from the circle.
You need two small changes to make your code work:
Change the loop to:
for (int i = 0; i < miniViewCount; i++)
And change the transform:
miniView.transform = CGAffineTransformRotate(miniView.transform, radians + arcStart + M_PI / 2.0);

Drop `points` along a UIBezierPath such that `center` of points lies ON the path

The problem statement:
Create a semi-circular dial that has dots along it's circumference. User can pan and rotate this dial.
Approach:
Created a UIView
Added a circle with radius that's double the height of the UIView (using [UIBezierPath bezierPathWithOvalInRect] and CAShapeLayer)
Add dots (circular CALayer objects) along the circumference of this circle, such that the center of these dots lies ON the circumference.
The obstacle:
The dots are plotted along a path, but the center of these dots does not lie on the circumference.
The code is as follows:
#property (nonatomic, retain) CAShapeLayer* dialLineLayer;
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
self.dialLineLayer = [CAShapeLayer layer];
CGRect path = CGRectMake(SCREEN_WIDTH /2 - self.radius, -self.radius, 2 * self.radius, 2 * self.radius);
[self.dialLineLayer setPath:[[UIBezierPath bezierPathWithOvalInRect:path] CGPath]];
[self.dialLineLayer setStrokeColor:[[UIColor la_white10Color] CGColor]];
[self.dialLineLayer setFillColor:[[UIColor clearColor] CGColor]];
[self.dialLineLayer setLineWidth:3.0f];
[self.layer addSublayer:self.dialLineLayer];
[self addDotsOnLineLayer];
}
return self;
}
- (CGFloat) radius {
// View has an aspect ratio constraint of 75:34 (W:H)
return SCREEN_WIDTH * 34 / 75 - 10; // Circle radius is 10px less that View's height
}
- (CGFloat) circumference {
return M_2_PI * self.radius; // 2Pi * radius
}
- (void) addDotsOnLineLayer {
CGPoint dotPoint = CGPointMake(SCREEN_WIDTH /2 - self.radius - self.radius/2, 0);
for (double t = 0; t < 2*M_PI; t += 0.2) {
CGFloat dotRadius = arc4random_uniform(10) - arc4random_uniform(3); // Random radius between 3px and 10px
CALayer* dotLayer = [CALayer layer];
dotLayer.frame = CGRectMake(dotPoint.x, dotPoint.y, dotRadius, dotRadius);
dotLayer.cornerRadius = dotRadius / 2;
dotLayer.masksToBounds = YES;
dotLayer.backgroundColor = [UIColor greenColor].CGColor;
dotPoint.x = self.radius * cos(t) + (SCREEN_WIDTH / 2);
dotPoint.y = self.radius * sin(t) + 0;
[self.dialLineLayer addSublayer:dotLayer];
}
}
Try this: (Brace for major 'doh' + facepalm ;) )
dotLayer.frame = CGRectMake(0, 0, dotRadius, dotRadius);
dotLayer.position = dotPoint;
Explanation
You are currently positioning the origin of your layer on the path. (Remove the corner radius and you'll see what I mean.) However, since you want the center of the layer on the path, you have to assign to .position.
Note that this is only true, as long as you leave the .anchorPoint property of the layer at {0.5, 0.5}.
See Core Animation Basics for more info.

Objective C - how to know if point is inside a quarter of circle?

I drew a quarter of a circle inside a rectangle.
Rectangle:
UIView *Rectangle = [[UIView alloc] initWithFrame:CGRectMake(0,0,[[UIScreen mainScreen] bounds].size.width,[[UIScreen mainScreen] bounds].size.height-292)];
Rectangle.backgroundColor = [UIColor lightGrayColor];
Rectangle.layer.zPosition = -5;
Quarter of Cirlce:
CGPoint center;
center.x = 0;
center.y = 0;
float radius = [[UIScreen mainScreen] bounds].size.width;
UIBezierPath *circle = [UIBezierPath bezierPathWithArcCenter:center
radius:radius
startAngle:0
endAngle:M_PI
clockwise:YES];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setPath:[circle CGPath]];
Then I added the rectangle in the view and added the circle inside the rectangle:
[self.view addSubview:Rectangle];
[Rectangle.layer addSublayer:circleLayer];
Then I started drawing little rectangles of 1 width and 1 height that I consider as points, and randomly added them into the view with a for loop, coloring the points inside the circle with green and points outside of the circle with red
int compteurPointsinCercle = 0 ;
int compteurPointsOutCercle = 0 ;
float XcenterCircle = center.x;
float YcenterCircle = center.y;
for (int i = 0 ; i < 50000 ; i++ )
{
float xvalue = arc4random_uniform([[UIScreen mainScreen] bounds].size.width);
float yvalue = arc4random_uniform([[UIScreen mainScreen] bounds].size.height-292);
// (x - center_x)^2 + (y - center_y)^2 < radius^2
float valeurPoint = (xvalue - XcenterCircle)*2 + (yvalue -YcenterCircle)*2;
NSLog(#"(Inside for), valeurPoint is : %f",valeurPoint);
if ( valeurPoint < (radius*2) )
{
// Point is inside of circle (green color)
compteurPointsinCercle++;
UIView *Rectangle2 = [[UIView alloc] initWithFrame:CGRectMake(xvalue,yvalue,1,1)];
Rectangle2.backgroundColor = [UIColor greenColor];
[self.view addSubview:Rectangle2];
}
else if ( valeurPoint > (radius*2) )
{
// Point is outside of circle (red color)
compteurPointsOutCercle++;
UIView *Rectangle2 = [[UIView alloc] initWithFrame:CGRectMake(xvalue,yvalue,1,1)];
Rectangle2.backgroundColor = [UIColor redColor];
[self.view addSubview:Rectangle2];
}
}
I test if the point is inside the circle using this :
float valeurPoint = (xvalue - XcenterCircle)*2 + (yvalue -YcenterCircle)*2;
where xvalue and yvalue are the coordinates of the point that will be created, and XcenterCircle and YcenterCircle are the coordiantes of the center of the circle.
I have something wrong because it gives me this result (it dosent test correctly if the point is inside the circle or not: a part of the points inside of the circle are considered outside):
can you tell me what I am doing wrong here ? and how can I exactly the points inside the circle ?
* is not power operation, it is multiplication.
float valeurPoint = (xvalue - XcenterCircle) * (xvalue - XcenterCircle) + (yvalue -YcenterCircle)*(yvalue -YcenterCircle);
if ( valeurPoint < (radius * radius) )
Should fix your problem
or using the pow function:
float valeurPoint = pow((xvalue - XcenterCircle), 2) + pow((yvalue -YcenterCircle), 2);
You can also use hypot function directly (although the performance can be slightly worse because of sqrt calculation)
float distance = hypotf((xvalue - XcenterCircle), (yvalue -YcenterCircle));
if (distance < radius)
EDIT:
Thanks #Alex for suggestion. The best solution is to use the native method -[UIBerierPath containsPoint:]. Then you won't have to calculate the distance at all.

text labels drawn in CGRect form an elliptical arc when images drawn using the same coordinates form a circular arc

I am new to Core Graphics and trying to understand why text labels I draw in CGRect form an elliptical arc when images I draw using the same coordinates form a circular arc.
The original code by Arthur Knopper creates circles wherever the screen is touched. By removing the touches method, I have been able to generate a series of small circles (dots) along a circular arc (uber circle). Each dot is centred on the perimeter of the uber circle (as shown below).
In order to label each dot I use the same point coordinates I used for placing the dot. However text labels form an elliptical arc even though dots form a circular arc (as shown below). Labels are also hidden by the dots when dots are filled. The reason for this is a complete mystery.
As a novice I am probably missing something basic in Core Graphics. If anyone could explain what that is and what I need to do to make both arcs circular and place labels on top of the dots I’d be most grateful.
Thanks.
Here is the code.
circleView.h
NSMutableArray *totalCircles;
int dotCount, limit;
float uberX, uberY, uberRadius, uberAngle, labelX,
labelY,dotRadius, dotsFilled, sectors, x, y;
CGPoint dotPosition;
CGRect boxBoundary;
CGContextRef context;
}
- (void)demo;
#end
And ...
-#implementation iOSCircleView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
totalCircles = [[NSMutableArray alloc] init];
// Set background color
self.backgroundColor = [UIColor whiteColor];
}
return self;
} // frame a view for drawing
- (void)drawRect:(CGRect)rect {
[self demo];
}
- (void)demo {
context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.5);
uberX = 120;
uberY = 160;
uberRadius = 30;
sectors = 16;
uberAngle = (2.0 * PI) / sectors;
dotRadius = 20;
dotsFilled = FALSE;
for (dotCount = 1; dotCount <= sectors; dotCount++)
{
// Create a new iOSCircle Object
iOSCircle *newCircle = [[iOSCircle alloc] init];
newCircle.circleRadius = dotRadius;
[self setSectorDotCoordinates]; // make new point for each dot
dotPosition = CGPointMake(x,y); // create each dot
NSLog(#"Circle%i: %#", dotCount, NSStringFromCGPoint(dotPosition));
[self autoLabel]; // text hides behind the dots
newCircle.circleCentre = dotPosition; // place each dot on the frame
[totalCircles addObject:newCircle];
[self setNeedsDisplay];
}
CGContextSetShadowWithColor(context, CGSizeMake(-3 , 2), 4.0, [UIColor clearColor].CGColor);
dotCount = 1;
for (iOSCircle *circle in totalCircles) {
CGContextAddArc(context, circle.circleCentre.x, circle.circleCentre.y, circle.circleRadius, 0.0, M_PI * 2.0, YES); // draw the circles
NSLog(#"Dot %i Filled %i ", dotCount, dotsFilled);
switch (dotsFilled) {
case 1:
CGContextSetFillColorWithColor(context, [[UIColor cyanColor] CGColor]);
//CGContextDrawPath(context, kCGPathFillStroke);
break;
default:
//CGContextStrokePath(context); // draw dot outline
break;
}
dotCount++;
}
} // draw circular dots in circular patterns
- (void)setSectorDotCoordinates {
x = uberX + (uberRadius * cos(uberAngle *dotCount) * 2);
y = uberY + (uberRadius * sin(uberAngle *dotCount) * 2);
} // calculate dot coordinates along a circular arc
- (void)autoLabel {
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
boxBoundary = CGRectMake(x-dotRadius, y-dotRadius, x+dotRadius, y+dotRadius);
[[NSString stringWithFormat:#"%i",dotCount] drawInRect:boxBoundary withFont:[UIFont systemFontOfSize:24] lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentCenter];
}
Change the boxBoundary in autoLabel, CGRectMake creates a rectangle with one point coordinates and width and height, not two points:
(void)autoLabel {
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
boxBoundary = CGRectMake(x-dotRadius, y-dotRadius, dotRadius*2, dotRadius*2);
[[NSString stringWithFormat:#"%i",dotCount] drawInRect:boxBoundary
withFont:[UIFont systemFontOfSize:24]
lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentCenter];
}
In your code the "boxes" containing the texts where bigger and bigger when you where going to the right. (the width and height were not fixed)
My updated code show labels that match the drawing order but text is still hidden when dots are filled.
I suspect I need to construct a path to write text in front of the dots and it’s already apparent that something like CGPathMoveToPoint is needed to start drawing from the 12 O'clock position.
Here’s the updated code. The first part draws and renders the dots
context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.5);
uberX = 160;
uberY = 240;
uberRadius = 52;
sectors = 16;
uberAngle = ((2.0 * PI) / sectors);
NSLog(#"%f %f %f %f", uberX, uberY, uberRadius, uberAngle);
dotRadius = 20;
dotsFilled = FALSE;
textOffset = 4; // add to y to centre the label
for (dotCount = 1; dotCount <= 4 /*sectors*/; dotCount++)
{
// Create a new iOSCircle Object
iOSCircle *newCircle = [[iOSCircle alloc] init];
newCircle.circleRadius = dotRadius;
[self setSectorDotCoordinates]; // create a new point for each dot
dotPosition = CGPointMake(x,y); // create each dot
NSLog(#"Circle%i: %#", dotCount, NSStringFromCGPoint(dotPosition));
newCircle.circleCentre = dotPosition; // place each dot on the frame
[totalCircles addObject:newCircle];
[self setNeedsDisplay];
}
CGContextSetShadowWithColor(context, CGSizeMake(-3 , 2), 4.0, [UIColor clearColor].CGColor);
dotCount = 1;
for (iOSCircle *circle in totalCircles) {
CGContextAddArc(context, circle.circleCentre.x, circle.circleCentre.y, circle.circleRadius, 0.0, M_PI * 2.0, YES);
// draw the circles
NSLog(#"Dot %i Filled %i ", dotCount, dotsFilled);
switch (dotsFilled) {
case 1:
CGContextSetFillColorWithColor(context, [[UIColor cyanColor] CGColor]);
CGContextDrawPath(context, kCGPathFillStroke);
break;
default:
CGContextStrokePath(context); // draw dot outline
break;
}
[self setSectorDotCoordinates]; // find point coordinates for each dot
dotCount++;
}
The code that draws the labels follow immediately afterwards.
// draw labels
for (dotCount = 1; dotCount <= sectors; dotCount++)
{
// Create a new iOSCircle Object
iOSCircle *newCircle = [[iOSCircle alloc] init];
newCircle.circleRadius = dotRadius;
[self setSectorDotCoordinates]; // find point coordinates for each dot
dotPosition = CGPointMake(x,y); // use point coordinates for label
[self autoLabel]; // THIS SHOWS TEXT BEHIND THE DOTS
}

Horizantal slider with tick marks on iOS

Can i realise a horizontal slider with tick marks on iOS? There is not such option like in MacOS.
I actually wrote a tutorial on how to do this on my company's website:
http://fragmentlabs.com/blog/making-talking2trees-part-3-77
The quick answer for this is a custom method I wrote, and which is explained in the article above:
-(UIView*)tickMarksViewForSlider:(UISlider*)slider View:(UIView *)view
{
// set up vars
int ticksDivider = (slider.maximumValue > 10) ? 10 : 1;
int ticks = (int) slider.maximumValue / ticksDivider;
int sliderWidth = 364;
float offsetOffset = (ticks < 10) ? 1.7 : 1.1;
offsetOffset = (ticks > 10) ? 0 : offsetOffset;
float offset = sliderWidth / ticks - offsetOffset;
float xPos = 0;
// initialize view to return
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y+1,
slider.frame.size.width, slider.frame.size.height);
view.backgroundColor = [UIColor clearColor];
// make a UIImageView with tick for each tick in the slider
for (int i=0; i < ticks; i++)
{
if (i == 0) {
xPos += offset+5.25;
}
else
{
UIView *tick = [[UIView alloc] initWithFrame:CGRectMake(xPos, 3, 2, 16)];
tick.backgroundColor = [UIColor colorWithWhite:0.7 alpha:1];
tick.layer.shadowColor = [[UIColor whiteColor] CGColor];
tick.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
tick.layer.shadowOpacity = 1.0f;
tick.layer.shadowRadius = 0.0f;
[view insertSubview:tick belowSubview:slider];
xPos += offset - 0.4;
}
}
// return the view
return view;
}
You'd basically apply this method to a view that sits behind your UISlider, and it creates the tick marks at the appropriate intervals. You can change how many ticks are visible by modifying the ticksDivider variable. The above example creates one per slider value unless the slider's maximumValue property is greater than 10 (my sliders had values of 5, 40 and 120), in which case I divided the value by 10.
You have to play with the offsetOffset value and the float value after xPos += offset+... to account for the width of your thumb image and slider cap insets (so the thumb button appears to be centered over each).
From #CarlGoldsmith - You'd have to program that yourself; UISliders on iOS don't have that functionality.
While ctlockey's solution certainly works, I wanted something simpler but also that allowed the thumb to snap to whichever tick mark it is closest to when the user releases it.
My solution is below. It is a subclass of UISlider that only overrides two methods. It is bare bones but would be a foundation for a more complex version.
-(void)endTrackingWithTouch:(UITouch *)touch
withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
if (self.value != floorf(self.value))
{
CGFloat roundedFloat = (float)roundf(self.value);
[self setValue:roundedFloat animated:YES];
}
}
-(void)drawRect:(CGRect)rect
{
CGFloat thumbOffset = self.currentThumbImage.size.width / 2.0f;
NSInteger numberOfTicksToDraw = roundf(self.maximumValue - self.minimumValue) + 1;
CGFloat distMinTickToMax = self.frame.size.width - (2 * thumbOffset);
CGFloat distBetweenTicks = distMinTickToMax / ((float)numberOfTicksToDraw - 1);
CGFloat xTickMarkPosition = thumbOffset; //will change as tick marks are drawn across slider
CGFloat yTickMarkStartingPosition = self.frame.size.height / 2; //will not change
CGFloat yTickMarkEndingPosition = self.frame.size.height; //will not change
UIBezierPath *tickPath = [UIBezierPath bezierPath];
for (int i = 0; i < numberOfTicksToDraw; i++)
{
[tickPath moveToPoint:CGPointMake(xTickMarkPosition, yTickMarkStartingPosition)];
[tickPath addLineToPoint:CGPointMake(xTickMarkPosition, yTickMarkEndingPosition)];
xTickMarkPosition += distBetweenTicks;
}
[tickPath stroke];
}

Resources