The UITableView I am using has a custom UItableViewCell. This custom cell has a subview (an UIView subclass) to it. I use the drawRect of the custom UIView subclass to place all the text to be displayed by the cell.
And in the drawRect (of UIView subclass) I do the following
/*
// This piece of code is called when setNeedsDisplay is called
*/
- (void)drawRect:(CGRect)rect
{
self.layer.cornerRadius = 10.0f;
self.layer.backgroundColor = [[UIColor orangeColor] CGColor];
self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
self.layer.borderWidth = 3.0f;
}
However my custom cell is a black square like this
But I do see the intended behavior if I select the row. Like shown below
Whats going on ?
Your drawRect: method does not draw anything; the code that you put in there belongs in your initWithFrame: implementation.
You should manipulate the layer configuration in the initializer; in your drawRect: you should call functions of your CGContextRef based on the state of the view. For example, to draw some text you would use CGContextShowTextAtPoint, to draw some lines you would use CGContextAddLineToPoint, and so on.
See this question for information on the relationship between drawRect: and the CALayer of your UIView.
Try to set self.layer.masksToBounds = YES and (maybe) self.opaque = NO during your UIView's (the one where drawRect is overridden) initialization. (see this question)
Try to disable the selection highlight of the cell by using
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
You are doing one mistake:
Please go to the view in side the UItableViewCell and check the background color it may be black or something others, Reset it to clear color then check your result,
Related
I have written drawRect as follows.
-(void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef cxt = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(cxt, 2.0);
CGContextSetStrokeColorWithColor(cxt, [UIColor redColor].CGColor);
CGContextMoveToPoint(cxt, 250.0 , 0.0);
CGContextAddLineToPoint(cxt, 250.0, 50.0);
CGContextStrokePath(cxt);
}
It draws red line. But When I set background view to cell line disappears. I have set view as follow.
UIView *view = [[UIView alloc] initWithFrame:cell.frame];
view.backgroundColor = [UIColor grayColor];
cell.backgroundView = view;
What is the problem? How backgrond view hides the line?
Please help
I guess you are in a UITableViewCell?
You should not overwrite drawRect of the cell itself. Instead put your drawing code in a custom backgroundView, or in a custom view within the contentView hierarchy. (depends on your planned result, probably backgroundView is correct for you)
The line is gone, because the backgroundView is a subview of the TableViewCell, so it is on top of the cell itself. (You can see this, if you use [UIColor colorWithWhite:0.0 alpha:0.5] as backgroundColor of your backgroundView.) There are many views on a UITableViewCell, it looks somewhat like this:
UITableViewCell
> BackgroundView
> (EditControl)
> ContentView
> (AccessoryView)
Agree with jaydee3 that you should not override UITableViewCell's drawRect, instead make your custom view class extending from UIView, extend drawRect there and do all the framing and coloring thing there, then set an instance of that view as your cell background view, its much better approach
When u already drawn background of that,u can't set background Color or image again for that cell.It overlays on what u drawn.
I have a UIView whose color is black and opacity is 0.9 or something like that. What I want to do is to fill the UIView with black portion, but a specified rectangular area should not get black. i.e. that particular rectangular area remains with clear color...
Any kind of help will be appreciated.
regards,
Imran
You can subclass UIView and override - (void)drawRect:(CGRect)rect
And do something of the following (untested, but used something similar myself);
- (void)drawRect:(CGRect)rect {
// fill the whole UIView with a color
[[UIColor colorWithRed:1 green:1 blue:1 0.9] setFill];
UIRectFill( rect );
// draw a rect
CGRect rectIntersection = CGRectIntersection(theRectIWantToDrawIn, rect);
[[UIColor clearColor] setFill];
UIRectFill( rectIntersection );
}
The code above draws a black view with a simulated clearColor hole in it at a certain position. You could, of course, alter this behavior to your liking.
This is quite fast.
UPDATE: Do note that I set the UIView on which I want to draw the rect to UIClear color (I added it to a xib and set those properties there) and unchecked 'Opaque'. That should make the hole see-through.
UPDATE 2: My answer was based on this answer (credit where credit is due): iPhone - Draw transparent rectangle on UIView to reveal view beneath
Add another view (subview) to that area. And set its to your desired color. Thats the easy solution with your current requirements.
Or you can use some quartz core functions.
You can create a small UIView in the main view by custom and set background clear color
UIView *View1 = [[UIView alloc] initWithFrame:CGRectMake(128.0f, 50.0f, 34.0f, 34.0f)];
[View1 setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:View1];
[View1 release];
I have my very own minimal view class with this:
- (void) awakeFromNib
{
NSLog(#"awakeFromNib!");
[self.layer setDelegate:self];
[self.layer setFrame:CGRectMake(30, 30, 250, 250)];
self.layer.masksToBounds = YES;
self.layer.cornerRadius = 5.0;
self.layer.backgroundColor = [[UIColor redColor] CGColor];
[self setNeedsDisplay];
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
NSLog(#"drawing!");
}
drawLayer:inContext never get called, although I can see the layer as red, rounded corner rectangle. What am I missing?
EDIT: from Apple docs
You can draw content for your layer,
or better encapsulate setting the
layer’s content image by creating a
delegate class that implements one of
the following methods: displayLayer:
or drawLayer:inContext:.
Implementing a delegate method to draw
the content does not automatically
cause the layer to draw using that
implementation. Instead, you must
explicitly tell a layer instance to
re-cache the content, either by
sending it a setNeedsDisplay or
setNeedsDisplayInRect: message, or by
setting its needsDisplayOnBoundsChange
property to YES.
Also
drawLayer:inContext:
If defined, called by the default implementation
of drawInContext:.
You should never change the delegate of layer of a UIView. From documentation of UIView layer property:
Warning: Since the view is the layer’s
delegate, you should never set the
view as a delegate of another CALayer
object. Additionally, you should never
change the delegate of this layer.
If you want to do custom drawing in a view simply override the drawRect: method.
If you do want to use layers you need to create your own:
UIView *myView = ...
CALayer *myLayer = [CALayer layer];
myLayer.delegate = self;
[myView.layer addSublayer:myLayer];
In both cases you need to call setNeedsDisplay on the view in the first case and on your custom layer in the second. You never call drawRect: or drawLayer:inContext: directly, they are called automatically when you call setNeedsDisplay.
Use
[self.layer setNeedsDisplay];
instead of
[self setNeedsDisplay];
It is the view.layer, not the view
Must I also do all this crazy coordinate system conversion stuff here, or is an UILabel different from an UIImageView drawing in -drawRect: ?
There's a method called - (void)drawTextInRect:(CGRect)rect for that.
BUT the documentation says: "You should not call this method directly. This method should only be overridden by subclasses that want to modify the default drawing behavior for the label’s text."
So? How to draw it then in -drawRect:?
UILabel is different in that you don't need to manually draw text to alter the way it is presented. Subclassing UILabel and overriding -drawTextInRect: is the quickest way to alter the way a UILabel is rendered. For example,
- (void)drawTextInRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadowWithColor( context, shadowOffset, shadowRadius, [shadowColor CGColor] );
[super drawTextInRect:rect];
}
will add a shadow with a specific offset, radius, and color (as a UIColor instance) to any text that you draw in that UILabel. For an example of this in action, see a project I put together for a recent class.
However, if what you are looking to do is just draw text within another view, Vladimir's answer is the way to go.
If you perform custom drawing in your view you must not draw UILabel or another UI element but rather draw text itself. NSString has several methods for drawing in current context (look at NSString's UIKit extension docs for more methods):
- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font
- (CGSize)drawAtPoint:(CGPoint)point withFont:(UIFont *)font
Actually you can do it.
Try this:
UILabel *lblRef = [[UILabel alloc] initWithFrame:CGRectMake(x, y, width, height)];
lblRef.text = [refs objectAtIndex:barCount];
lblRef.adjustsFontSizeToFitWidth = TRUE;
lblRef.adjustsLetterSpacingToFitWidth = TRUE;
lblRef.textColor = self.color;
[lblRef setTextAlignment:NSTextAlignmentCenter];
lblRef.backgroundColor = [UIColor clearColor];
[self addSubview:lblRef];
Can anyone help me with this. I need to do custom drawing code in -drawRect so I subclassed UIImage. How would I initialize my custom UIImage with an image? Say I override the imageName method, what would I need to do in this method? After initializing can I add it to a UIImageview like so initwithImage:?
If you're going to do custom drawing, don't subclass UIImage, subclass UIView, and add your subclass view to wherever you want the custom drawing to be. Do all of your drawing directly in the -drawRect: method of UIView. An example of how to draw a diagonal blue line:
-(void) drawRect:(CGRect)rect {
CGContextRef g = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(g,self.frame.origin.x,self.frame.origin.y);
[[UIColor blueColor] setStroke];
CGContextAddLineToPoint(g,CGRectGetMaxX(self.frame),CGRectGetMaxY(self.frame));
}