25

When I add a UIView to a View Controller programmatically I am not able to change the background color to any other color, it always remains black.

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    self.backgroundColor = [UIColor blueColor];

    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(100, 33)];
    [path addLineToPoint:CGPointMake(200, 33)];
    path.lineWidth = 5;
    [[UIColor redColor] setStroke];
    [path stroke];
}

When I comment drawrect: out and add self.backgroundColor = [UIColor blueColor]; to the initializer the color changes:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor = [UIColor blueColor]
    }
    return self;
}

Why is this and what do I need to change? Actually I would like the background to be transparent.

Tulon
  • 4,011
  • 6
  • 36
  • 56
Pete
  • 613
  • 1
  • 6
  • 18

4 Answers4

35

As you are implementing drawRect: this will override any default drawing of the UIView.

You must set the opaque property of your custom view to NO and clear the context before you render the path:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.opaque = NO;
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);

    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(100, 33)];
    [path addLineToPoint:CGPointMake(200, 33)];
    path.lineWidth = 5;
    [[UIColor redColor] setStroke];
    [path stroke];
}

https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/occ/instp/UIView/opaque

An opaque view is expected to fill its bounds with entirely opaque content—that is, the content should have an alpha value of 1.0. If the view is opaque and either does not fill its bounds or contains wholly or partially transparent content, the results are unpredictable. You should always set the value of this property to NO if the view is fully or partially transparent.

iOSX
  • 1,270
  • 13
  • 18
  • 1
    When I use this command, the background remains black for some reason. Solution does not work for me. Why could this be? – Pete May 11 '14 at 15:05
  • 1
    I've corrected my answer. It's important to set the opaque property of the view to NO. – iOSX May 11 '14 at 15:52
  • Why it doesn't work any more, as along as I clear the rect before drawing, the result view will have a black background, whether `isOpaque` set to `true` or `false`. – K.F Jun 11 '21 at 09:53
20

backgroundColor of your view is ignored if you draw view yourself using drawRect. Change your code to

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    [[UIColor blueColor] setFill];  // changes are here
    UIRectFill(rect);               // and here 

    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(100, 33)];
    [path addLineToPoint:CGPointMake(200, 33)];
    path.lineWidth = 5;
    [[UIColor redColor] setStroke];
    [path stroke];
}
Avt
  • 16,927
  • 4
  • 52
  • 72
  • 4
    Answer works perfectly when I want a background color. But I cannot use [[UIColor clearColor] setFill]; It still comes out black. – Pete May 11 '14 at 15:04
  • 7
    @Pete, I see the same result as you do when trying to set the color to clear in drawRect. To fix that, delete that UIRectFill call and set the background color to clear in the view's init method (which ever init method is appropriate for the way you create the view). – rdelmar May 11 '14 at 15:57
  • 3
    @Pete Please check this question http://stackoverflow.com/questions/2125543/setting-a-cgcontext-transparent-background. Maybe it will help – Avt May 11 '14 at 20:26
  • 7
    @Pete Also check that your view's `opaque` property is NO. i.e. `your_view.opaque = NO`. – Avt May 11 '14 at 20:28
2

Set the background color in initWithFrame: method and do your custom drawing inside drawRect:. That should be able to solve your problem. The drawRect: is implemented in order to do custom drawing not to set view specific properties.

@implementation MyView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
      self.backgroundColor = [UIColor yellowColor];
    }
    return self;
}
- (void)drawRect:(CGRect)rect{
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(100, 33)];
    [path addLineToPoint:CGPointMake(200, 33)];
    path.lineWidth = 5;
    [[UIColor redColor] setStroke];
    [path stroke];

}

@end
Sandeep
  • 20,908
  • 7
  • 66
  • 106
1
backgroundViewController.providesPresentationContextTransitionStyle = YES;
backgroundController.definesPresentationContext = YES;
[overlayViewController setModalPresentationStyle:UIModalPresentationOverCurrentContext];

or

enter image description here

I struggled for many hours . If its a model segue, set over current context as property. !

Milad Faridnia
  • 9,113
  • 13
  • 65
  • 78
Alvin George
  • 14,148
  • 92
  • 64