重叠透明的UIViews

时间:2014-10-14 15:27:09

标签: ios objective-c uiview core-graphics compositing

我用两个UIViews覆盖了白色backgroundColor,不透明度为25%。在一小部分中,它们彼此重叠,这意味着在该区域,它们总和为50%的不透明度。

我希望保持25%的不透明度,即使两个视图重叠,实际上意味着在这些重叠点中,每个视图的不透明度下降到12.5%,总计25%。

我已经对复合做了一些研究,但我不确定这些模式中的哪一种会有所帮助,或者我将如何将它们应用于这两个UIView实例的特定部分。

http://docs.oracle.com/javase/tutorial/2d/advanced/compositing.html就是我正在阅读的内容,我发现CGBlendMode用于绘图,如果要使用它(尽管如果可能的话我不想这样做!)

2 个答案:

答案 0 :(得分:1)

如果您将它们都添加到同一个父UIView,请告诉UIView进行栅格化,然后在父级上设置alpha,您将获得所需的效果。我不确定这是否符合您的显示器结构或性能需求。

UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[parent setBackgroundColor:[UIColor clearColor]];
[parent.layer setShouldRasterize:YES];
[parent.layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[parent setAlpha:0.25];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 125, 125)];
[subview1 setBackgroundColor:[UIColor whiteColor]];
[parent addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectMake(75, 75, 125, 125)];
[subview2 setBackgroundColor:[UIColor whiteColor]];
[parent addSubview:subview2];

答案 1 :(得分:1)

您无法在iOS上控制视图的合成模式(或者,实际上是CALayer)。

我能想到的最佳解决方案是将两个视图保留为clearColor(或nil)背景,并使用单个CAShapeLayer绘制两者的背景。如果你的两个观点有相同的父母,那就不太难了。

我们说父母的类型为ParentView。覆盖layoutSubviews中的ParentView以根据需要创建和更新背景图层。如果移动任一子视图,请务必将setNeedsLayout发送到父视图。

ParentView.h

#import <UIKit/UIKit.h>

@interface ParentView : UIView

@property (nonatomic, strong) IBOutlet UIView *childView0;
@property (nonatomic, strong) IBOutlet UIView *childView1;

@end

ParentView.m

#import "ParentView.h"

@implementation ParentView {
    CAShapeLayer *backdrop;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self layoutBackdrop];
}

- (void)layoutBackdrop {
    [self createBackdropIfNeeded];
    [self arrangeBackdropBehindChildren];
    [self setBackdropPath];
}

- (void)createBackdropIfNeeded {
    if (backdrop == nil) {
        backdrop = [CAShapeLayer layer];
        backdrop.fillColor = [UIColor colorWithWhite:1 alpha:0.25].CGColor;
        backdrop.fillRule = kCAFillRuleNonZero;
        backdrop.strokeColor = nil;
    }
}

- (void)arrangeBackdropBehindChildren {
    [self.layer insertSublayer:backdrop atIndex:0];
}

- (void)setBackdropPath {
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.childView0.frame];
    [path appendPath:[UIBezierPath bezierPathWithRect:self.childView1.frame]];
    backdrop.path = path.CGPath;
}

@end