Can't draw in UITableViewCell's drawRect - ios

I'm having trouble drawing in the drawRect method of my custom UITableViewCell. Here is the code I am using
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGPoint origin = _faceView.frame.origin;
CGFloat width = _faceView.frame.size.width;
CGFloat height = _faceView.frame.size.height;
CGFloat border = 2.0f;
CGPoint startPt = CGPointMake(origin.x + width/2, self.frame.size.height);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, startPt.x, startPt.y);
CGPoint basePt = CGPointMake(startPt.x, origin.y - height - border);
CGContextAddLineToPoint(ctx, basePt.x, basePt.y);
CGRect circleRect = CGRectMake(origin.x - border, origin.y - border, width + 2 * border, height + 2 * border);
CGContextAddEllipseInRect(ctx, circleRect);
UIColor *color = [UIColor redColor];
CGContextSetFillColorWithColor(ctx, color.CGColor);
CGContextSetStrokeColorWithColor(ctx, color.CGColor);
CGContextSetLineWidth(ctx, 1.0f);
CGContextDrawPath(ctx, kCGPathFillStroke);
}
I've debugged to make sure that all of the numeric values make sense and it appears that they do. Can't really find out why nothing is being drawn on screen.
For what its worth, this is a cell defined in a nib as well. And i'm building with the iOS 7 sdk.
Any ideas?
tahnks

Try set backgroungcolor property to transparent color
self.backgroundColor = [UIColor clearColor]

You probably shouldn't do this in UITableViewCell's own drawRect. Instead, create a custom UIView and add it as a subview.
See also this answer.

You have to set
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
.....
[cell setNeedsDisplay];
return cell;
}

Try set backgroundColor of contentView property to clear color
self.contentView = [UIColor clearColor];

Related

How to get rid of thin border in a UIView rounded with layer.cornerRadius in iOS 7.1.1?

I have a customized UIView that rounds its corners by using layer.cornerRadius like this:
- (void)layoutSubviews
{
[super layoutSubviews];
self.layer.cornerRadius = self.frame.size.width / 2.0;
self.layer.borderColor = [UIColor whiteColor].CGColor;
self.layer.borderWidth = 2.0;
self.layer.masksToBounds = YES;
self.backgroundColor = [UIColor redColor];
}
How can I get rid of the very thin outer red circle?
Well, a more efficient way to do what you need would be to copy paste this function in the .m file of your custom view and call it in the drawRect method:
- (void)drawRoundedViewWithFrame: (CGRect)frame color:(UIColor *)color
{
//// roundCircle Drawing
UIBezierPath* roundCirclePath = [UIBezierPath bezierPathWithOvalInRect: frame];
[color setFill];
[roundCirclePath fill];
[UIColor.whiteColor setStroke];
roundCirclePath.lineWidth = 2;
[roundCirclePath stroke];
}
Based on an answer in here, I figured out a way to do this with these steps:
Set the UIView background color to [UIColor clearColor]
Manually draw a smaller circular background in drawRect:
Here's the drawRect: implementation:
- (void)drawRect:(CGRect)rect
{
CGFloat margin = _borderWidth;
CGRect background = CGRectMake(margin, margin,
self.bounds.size.width - 2 * margin,
self.bounds.size.height - 2 * margin);
CGContextRef context = UIGraphicsGetCurrentContext();
[_internalBackgroundColor set];
CGContextFillEllipseInRect(context, background);
}
And the overwritten backgroundColor setter:
#property (nonatomic, strong) UIColor *internalBackgroundColor;
...
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
[super setBackgroundColor:[UIColor clearColor]];
_internalBackgroundColor = backgroundColor;
}
**** Faster solution: ****
As Kujey pointed out, it's better not to use the layer.cornerRadius at all. Here's the drawRect: solution without the layer access:
- (void)drawRect:(CGRect)rect
{
CGFloat margin = _borderWidth / 2.0;
CGRect background = CGRectMake(margin, margin, self.bounds.size.width - 2 * margin, self.bounds.size.height - 2 * margin);
CGContextRef context = UIGraphicsGetCurrentContext();
[_internalBackgroundColor set];
CGContextFillEllipseInRect(context, background);
[_borderColor set];
CGContextSetLineWidth(context, _borderWidth);
CGContextStrokeEllipseInRect(context, background);
}

How to add an UIActivityIndicator into a drawRect

I want to know how could I add an activity indicator (in the middle of a HUD) to this drawrect method (i'm trying to create a hud with the activity on it)
- (void)drawRect:(CGRect)rect {
// Sets the rectangle to be 96 X 96.
const CGFloat boxWidth = 120.0f;
const CGFloat boxHeight = 120.0f;
// This method is used to calculate the position of the rectangle.
CGRect boxRect = CGRectMake( roundf(self.bounds.size.width - boxWidth) / 2.0f, roundf(self.bounds.size.height - boxHeight) / 2.0f, boxWidth,boxHeight);
// This draws the rectangle with rounded corners.
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:boxRect cornerRadius:10.0f];
[[UIColor colorWithWhite:0.0f alpha:0.75] setFill];
[roundedRect fill];
[[UIColor whiteColor] set]; // Sets the color of the font to white.
UIFont *font = [UIFont boldSystemFontOfSize:16.0f]; // Sets the size of the font to 16.
CGSize textSize = [self.text sizeWithFont:font];
// Calculates where to draw the text.
CGPoint textPoint = CGPointMake( self.center.x - roundf(textSize.width / 2.0f), self.center.y - roundf(textSize.height / 2.0f) + boxHeight / 4.0f);
// Draws the text on the rectangle.
[self.text drawAtPoint:textPoint withFont:font];
}
Thanks!
You don't. Activity indicator is a type of view, so you'd add it as a subview of your HUD and it will draw itself.

iOS drawRect with custom height

I have placed a view on a viewController and I want to draw a rectangle in this view, but with a custom height. I determine the height based on a parameter in my viewController.
So for example. If my parameter is 50, I want the rectangle to have the height of 50% of the UIView.
2 questions:
how can I pass the height to the custom drawRect?
how do I make the rectangle be placed on the bottom of the UIView?
I have placed the view using Interface Builder and I have implemented the drawRect in a subclass of UIView and used this as Custom Class for my UIView.
So in the custom class I have:
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor * lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0];
CGRect paperRect = self.bounds;
drawLinearGradient(context, paperRect, lightGrayColor.CGColor, [UIColor clearColor].CGColor);
}
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = #[(__bridge id) startColor, (__bridge id) endColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
This draws a nice gradient rectangle in my view but it fills the complete UIView.
This is because of the self.bounds.
I have added a property *height to my custom class, but I don't know how to fill this from my viewController. So I want it to start at the bottom off the UIView, and make it as high as I have determined (a % of the real height).
Anybody knows how I can achieve this?
have you set your custom view class in identity inspector in interface builder?
you can set the height property from your viewController:
((MyViewClass *) self.myView).height = myCalculatedValue;
then implement drawRect:
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor * lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0];
CGRect paperRect = self.bounds;
paperRect.origin.y = paperRect.size.height - self.height;
paperRect.size.height = self.height;
//assuming your height property is of CGFloat type
drawLinearGradient(context, paperRect, lightGrayColor.CGColor, [UIColor clearColor].CGColor);
}
this will draw your gradient from (height) points above the bottom to the bottom
I think you can get calculate 50% of screen height and then substract new view height from the full screen Height
youParameter = 50; // Lets assume this is your parametere
int heightOfView = ([UIScreen mainScreen].bounds.size.height * yourParameter) / 100;
// For placing the view to the bottom;
CGRect newFrame;
frame.origin.y = [UIScreen mainScreen].bounds.size.height - heightOfView;
frame.origin.x = 0;
frame.size.width = [UIScreen mainScreen].bounds.size.width; // assuming it will take full width
frame.size.height = heightOfView;
youViewToChange.frame = newFrame; // normally do this or
To pass the value to drawRect you can do:
[self drawRect:newFrame];

iOS: Draw clear circle with UIBezierPath bezierPathWithOvalInRect:

In my UITableViewController's cells, I want to display a circle with a number in it. I am using UIBezierPath's bezierPathWithOvalInRect: to draw the circle.
Unfortunately, while I can set the fill color to be clearColor, the unused portion of the CGRect passed to bezierPathWithOvalInRect: is black.
How do I get rid of the black area created?
Partial screenshot for reference:
(I eventually hope to get that number inside the circle)
Code:
LTTTableViewCell:
- (void)awakeFromNib {
[super awakeFromNib];
// Create a square view using the height of the cell
CGRect positionFrame = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.height);
LTTDrawBallView *drawBallView = [[LTTDrawBallView alloc] initWithFrame:positionFrame];
[self.contentView addSubview:drawBallView];
}
LTTDrawBallView:
- (void)drawRect:(CGRect)rect
{
// Create a new rect with some padding
// + create a circle from this new rect:
CGRect box = CGRectInset(self.bounds, self.bounds.size.width * 0.1f, self.bounds.size.height * 0.1f);
UIBezierPath *ballBezierPath = [UIBezierPath bezierPathWithOvalInRect:box];
[[UIColor whiteColor] setStroke];
[[UIColor greenColor] setFill]; // Green here to show the black area
[ballBezierPath stroke];
[ballBezierPath fill];
[self setBackgroundColor:[UIColor clearColor]]; // Happens with and without this line
}
In the init method of your LTTDrawBallView, include the code:
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];

How to remove border from some part of UIView?

I am having a UIView which contains other subviews. I am applying border to this UIView and the border is applied to the whole UIView. For that see the first image.
But do not want the border around the title where it says "Leaderboard". How can i remove the border for that portion only. See the below image and in that see that there is no border around the header Leaderboard..
NO,CALayer borders don’t support that behavior.
But you can try an alternate method if you need to implement this,
try adding an n-point-wide opaque subview with your desired border color as its background color, on each side of your main view.
Add this Code:
CGSize mainViewSize = theView.bounds.size;
CGFloat borderWidth = 2;
UIColor *borderColor = [UIColor redColor];
CGFloat heightfromTop = 25;
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, heightfromTop borderWidth, mainViewSize.height-heightfromTop)];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(mainViewSize.width - borderWidth, heightfromTop, borderWidth, mainViewSize.height-heightfromTop)];
leftView.opaque = YES;
rightView.opaque = YES;
leftView.backgroundColor = borderColor;
rightView.backgroundColor = borderColor;
[mainView addSubview:leftView];
[mainView addSubview:rightView];
This will add borders to both sides only.Repeat the same idea for top and bottom also.
NB : heightfromTop is the height of the top section where you don't want the border view to be present, you can alter it as per your needs
You can subclass the UIView and implement the drawRect like:
- (void)drawRect:(CGRect)rect
{
float borderSize = 3.0f;
//draw the bottom border
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0.0f, self.frame.size.height - borderSize, self.frame.size.width, borderSize));
//draw the right border
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0.0f,0.0f, borderSize,self.frame.size.height));
//draw the left border
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(self.frame.size.width - borderSize,0.0f, borderSize,self.frame.size.height));
}
Now, you need to use the subclassed UIView for creating the needed view.

Resources