【问题标题】:Setting A CGContext Transparent Background设置 CGContext 透明背景
【发布时间】:2010-01-24 01:38:55
【问题描述】:

我仍在努力用 CGContext 画一条线。我实际上已经去画线了,但现在我需要 Rect 的背景是透明的,这样现有的背景才能显示出来。这是我的测试代码:

(void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
    CGContextSetAlpha(context,0.0);
    CGContextFillRect(context, rect);

    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextSetLineWidth(context, 5.0);
    CGContextMoveToPoint(context, 100.0,0.0);
    CGContextAddLineToPoint(context,100.0, 100.0);
    CGContextStrokePath(context);
}

有什么想法吗?

【问题讨论】:

    标签: iphone graphics background transparent cgcontext


    【解决方案1】:

    UIGraphicsGetCurrentContext()之后调用CGContextClearRect(context,rect)

    编辑: 好的,知道了。

    您的自定义视图应具有以下内容:

    - (id)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            [self setBackgroundColor:[UIColor clearColor]];
        }
        return self;
    }
    
    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextClearRect(context, rect);
        CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextSetLineWidth(context, 5.0);
        CGContextMoveToPoint(context, 100.0,0.0);
        CGContextAddLineToPoint(context,100.0, 100.0);
        CGContextStrokePath(context);
    }
    

    我的测试使用它作为一个非常基本的 UIViewController:

    - (void)viewDidLoad {
        [super viewDidLoad];
        UIImageView *v = [[UIImageView alloc] initWithFrame:self.view.bounds];
        [v setBackgroundColor:[UIColor redColor]];
        [self.view addSubview:v];
        TopView *t = [[TopView alloc] initWithFrame:self.view.bounds];
        [self.view addSubview:t];
        [v release];
        [t release];
    }
    

    【讨论】:

    • 背景为黑色,必须是iphone背景。我实际上是在尝试在 UIView 上绘图。
    • 我不太明白。您确定将 UIView 添加到超级视图吗?这个 drawRect 是在你想在上面绘制的 UIView 中,还是在不同的 UIView 中?你是不是不小心给这个 UIView 设置了背景色?
    • 感谢您的提问。我希望 IM 将 UIView 添加到它的超级视图中。绘制矩形肯定在视图中,因为该线已正确绘制。是的,我已经在 UIView 中设置了一个背景,这就是我想要展示的背景。我要做的就是在现有视图的顶部画一条线。在西雅图感到沮丧。
    • 清除矩形在这里不做。
    【解决方案2】:

    简单的方法:

    - (id)initWithFrame:(CGRect)frame
    {
        if ((self = [super initWithFrame:frame]))
        {       
            self.opaque = NO;
        }
        return self;
    }
    
    - (void)drawRect:(CGRect)rect
    {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextClearRect(context, rect);
        //your code
    }
    

    【讨论】:

    • 我将它用于表格视图单元格中的附件指示器。 self.opaque = NO 有效,而接受的答案中的 [self setBackgroundColor:[UIColor clearColor]] 无效。
    • self.opaque = false 在创建 UICollectionViewCell 的自定义子视图时帮助了我
    • 这应该是一个可以接受的答案。 self.opaque = NO 使使用 drawRect 的视图透明。谢谢!
    【解决方案3】:

    使用opaque == false,Swift 3 初始化上下文

    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) 
    

    不透明

    指示位图是否不透明的布尔标志。如果您知道位图完全不透明,请指定 true 以忽略 Alpha 通道并优化位图的存储。指定 false 意味着位图必须包含一个 alpha 通道来处理任何部分透明的像素。

    【讨论】:

    • 这也是我的问题。尽管isOpaque 是真实的,但屏幕上的图层是透明的。所以我放弃了self.isOpaque 作为第二个参数,并想知道为什么结果UIImage 不是。
    • 不要忘记关闭上下文以避免内存泄漏:UIGraphicsEndImageContext()
    【解决方案4】:

    这对我有用的 UIImage 是使用 InterfaceBuilder 手动添加的。

    - (id)initWithCoder:(NSCoder *)aDecoder {
    
        if(self = [super initWithCoder:aDecoder]) {
            self.backgroundColor = [UIColor clearColor];
        }
    
        return self;
    }
    
    
    -(void)drawRect:(CGRect)rect
    {
        CGContextRef context = UIGraphicsGetCurrentContext();    
        CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextSetLineWidth(context, 5.0);
        CGContextMoveToPoint(context, 100.0,0.0);
        CGContextAddLineToPoint(context,100.0, 100.0);
        CGContextStrokePath(context);
    }
    

    David Kanarek 的回答仅在您手动创建自己的 UIImageView 时有效。如果您创建了一个 UIView 并通过 Interface Builder 手动添加它,那么您将需要一种不同的方法,例如调用 initWithCoder 方法。

    【讨论】:

      【解决方案5】:

      我有同样的问题,然后我发现它是。 我覆盖init方法是-(id)initWithFrame:(CGRect)rect. 在这个方法self.background = [UIColor clearColor]; 但我在 xib 文件中使用此视图!那会调用init方法的是

      -(id)initWithCoder:(NSCoder*)aDecoder;
      

      所以覆盖所有的init方法,设置BackgroundColor就可以了。

      【讨论】:

      • 上述方法都不适合我,即使它是在 xib 中设置的,只是在代码中设置它就可以了。 +1
      【解决方案6】:
      CGContextClearRect(context,rect) 
      

      如果提供的上下文是窗口或位图上下文,Quartz 会有效地清除矩形。对于其他上下文类型,Quartz 以设备相关的方式填充矩形。但是,您不应在窗口或位图上下文以外的上下文中使用此函数。

      【讨论】:

        【解决方案7】:

        您可以使用以下代码创建图像上下文:

        cacheContext = CGBitmapContextCreate (cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
        CGContextSetRGBFillColor(cacheContext, 0, 0, 0, 0);
        CGContextFillRect(cacheContext, (CGRect){CGPointZero, size});
        

        关键是 kCGImageAlphaPremultipliedLast。

        【讨论】:

          【解决方案8】:

          无法理解这里的问题,但如果您无法通过您正在绘制的“顶部”视图显示“背景”UIView,则一种解决方案是 topView.backgroundColor = [UIColor clearColor]; 我有(我认为)同样的问题,这为我解决了。

          【讨论】: