I just want to draw a simple rectangle to a view using the following function:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
if (self.drawTextBouble) {
[[UIColor blueColor] setFill];
UIBezierPath *aPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(40, 0, 230, 120) cornerRadius:12.0];
[aPath fill];
}
}
The code above fills the view with plain black background, outside the rectangle is not transparent. How can I fix this?
Edit:
The solution below is working, but this is working also:
[self setOpaque:NO];
You drawing code is OK. If you want the custom drawn view to have transparent background, you just need to set
self.backgroundColor = [UIColor clearColor];
in view's - (id)initWithFrame:(CGRect)frame
Edit: Just a little note regarding calling [super drawRect:rect]. UIView docs says:
If you subclass UIView directly, your implementation of this method does not need to call super. However, if you are subclassing a different view class, you should call super at some point in your implementation.
Related
I have a custom view drawing colored path, worked well before React Native 0.19
But on React Native 0.19, it seems like there is a default black background, which prevent me from using translucent colors.
It looks like this on React Native 0.19:
If I draw nothing or some translucent color on the entire rect, you'll see the black layer
- (void)drawRect:(CGRect)rect
{
[[UIColor colorWithWhite:0 alpha:0] setFill];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, 20, 20)];
[[UIColor redColor] setFill];
[path fill];
}
please help me fix this problem.
React Native v0.19.0
running on iPhone 6s Plus (9.2) simulator
It's common when you override -drawRect to perform custom drawing, you need to set its opaque to NO or set its background colour manually in -initWithFrame:
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setOpaque:NO];
// or [self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
Btw, it's not black though we see it in black. It's just because there's no colour offered there to be shown appropriately, cause you override -drawRect, you take charge of the drawing related logic, but you did't take care of this area as expected.
I'm well aware that this question has been asked many times, but clearly something is different. I'm drawing rectangles over faces in a UIImageView and so I need the rectangles to be transparent.
As far as I can see, I'm following all recommendations to draw a transparent background in a view (e.g. clear the rect of the current graphics context). I'm also setting the view to not be be opaque and setting the backgroundColor to be clearColor. Are there other steps necessary?
-(instancetype)init
{
self = [super init];
if ( self ) {
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
self.clearsContextBeforeDrawing = NO;
}
return self;
}
- (void)drawRect:(CGRect)rect {
UIBezierPath * path = [UIBezierPath bezierPathWithRect:rect];
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor clearColor] setFill];
CGContextClearRect(ctx, rect);
[self.rectColor setStroke];
path.lineWidth = 5.0;
[path stroke];
}
#end
I need the background to be transparent, and this view just shows up black by default. I've tried to clearing the rectangle of the CGContext directly, as I've heard this is (was) commonly the solution.
I'm guessing that your init method is never called (after all, this is not the designated initializer), and so your code never runs and thus the views are created opaque.
I am following a video tutorial from pluralsight that draws a red rectangle to the screen. I have a subclass of UIView called PSViewDemo that has the following code in the .m file:
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, CGRectMake(40, 400,100,200));
// Drawing code
}
I call it in the Viewdidload of the viewcontroller for the only view in the application (until the code adds the subview).
- (void)viewDidLoad
{
[super viewDidLoad];
PSViewDemo *dv = [[PSViewDemo alloc] initWithFrame:CGRectMake( 0, 0, 320, 480)];
[self.view addSubview:dv];
// Do any additional setup after loading the view, typically from a nib.
}
The whole thing compiles and runs without error but there is no red rectangle on the screen.
What am I missing? I am pretty sure I am following the tutorial exactly so maybe something has changed in Cocoa since the tutorial was made? I'm using xCode 5.
Change
CGContextSetFillColor(context, [UIColor redColor].CGColor);
To
CGContextSetFillColor(context, CGColorGetComponents([[UIColor redColor] CGColor]));
My goal is to add gradients for my uilabel by doing the following (CustomLabelBackGround is subclass of UILabel)
#implementation CustomLabelBackGround
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor;
CGColorRef lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0].CGColor;
CGColorRef separatorColor = [UIColor colorWithRed:208.0/255.0 green:208.0/255.0 blue:208.0/255.0 alpha:1.0].CGColor;
CGRect paperRect = self.bounds;
// Fill with gradient
drawLinearGradient(context, paperRect, whiteColor, lightGrayColor);
// Add white 1 px stroke
CGRect strokeRect = paperRect;
strokeRect.size.height -= 1;
strokeRect = rectFor1PxStroke(strokeRect);
CGContextSetStrokeColorWithColor(context, whiteColor);
CGContextSetLineWidth(context, 1.0);
CGContextStrokeRect(context, strokeRect);
// Add separator
CGPoint startPoint = CGPointMake(paperRect.origin.x, paperRect.origin.y + paperRect.size.height - 1);
CGPoint endPoint = CGPointMake(paperRect.origin.x + paperRect.size.width - 1, paperRect.origin.y + paperRect.size.height - 1);
draw1PxStroke(context, startPoint, endPoint, separatorColor);
}
However, the text of CustomLabelBackGround is disappearing when I am trying to display onto the screen. please look at the picture below as reference:
What I am missing here. Please help if you have any ideas about this. thanks
You need to call :
[super drawRect:rect];
in order to super draw your text before drawing your anything else. The text with then be drawn normaly
Since you are implementing drawRect for UILabel you are owning that Graphics Context, therefore you are basically "overriding" the text, you can draw that yourself as well, or an easier approach would just be to have a container view with the gradient and a transparent label with the text.
The best approach
Create a custom UIView
make this drawrect implement there
In this UILabel class add that class as background to the label
Otherwise you have to draw the label contents also since you are overriding its drawrect method
Why not just pre-render the gradient in photoshop and then on your label just set:
myLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"myImage"]];
I would:
Create a custom UIView,and use your drawRect code there.
Make sure that the UILabel background is set to [UIColor
clearColor].
Add the Custom UILabel Class as a
subview of the Custom UIView class.
Or just do like Imram said, and create that gradient as an image in Photoshop or some other graphic editor program, and set the label background there. Personally, I think this may be the simplest and most maintainable solution.
I thought from some point on for OS X, and always true for iOS, that content can appear outside of the view's bounds? (for UIView) But if I create a brand new Single View app, and created a MyView class that subclasses UIView, and implement its drawRect:
- (void)drawRect:(CGRect)rect
{
// Drawing code
UIBezierPath *path = [UIBezierPath bezierPathWithRect:
CGRectMake(-20, -20, 600, 600)];
[[UIColor greenColor] set];
[path fill];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor blueColor] CGColor]);
CGContextFillRect(context, CGRectMake(-20, -20, 600, 600));
}
I use both UI and CG to draw a rectangle each, just in case one works and the other doesn't. And the view is added in viewDidAppear:
- (void)viewDidAppear:(BOOL)animated {
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(20, 20, 260, 260)];
[self.view addSubview:myView];
}
But no matter what, the colored box won't go beyond the (20, 20, 260, 260) region. Is it true that only the CALayers can be freely added and appear outside of a view's bounds? Can it be because of the graphics context is limited to this (20, 20, 260, 260) to begin with? If so, is there a way to make drawRect content appear outside of the view's bound, in all four top, down, left, right directions?
Your problem is that "drawRect" is automatically clipped to the view that you are drawing in.
Instead of doing the drawing in the view itself, add a second (sub)view to the first view, that is outside the bounds of the first view. This will allow you to do drawing that is dependent on the placement of the first view, but is outside the first view's bounds.
Hope this helps.
Try this on a view, where you have added the scrollView:
self.scrollView.backgroundColor = [UIColor darkGrayColor];
self.scrollView.layer.cornerRadius = 10.0f;
self.scrollView.layer.masksToBounds = YES;
It should display a gray scrollview with rounded corners, as you want.
Remember you need to import the QuartzCore FrameWork