将 CAShapeLayer 应用于除 UIButton 之外的主 UIView
Apply CAShapeLayer to main UIView except UIButton
下面是对整个 UIView 应用蒙版的代码:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
[maskPath appendPath:[UIBezierPath bezierPathWithArcCenter:self.mapCardsButton.center
radius:self.mapCardsButton.frame.size.height/2.0f
startAngle:0.0f
endAngle:2.0f*M_PI
clockwise:NO]];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.path = maskPath.CGPath;
self.view.layer.mask = maskLayer;
问题是我想将上面的掩码应用到整个 UIView,除了一个特定的 UIButton(mapCardsButton),它也在同一个 UIView 上。
可以吗?
UPD:我试过了
[self.view.layer insertSublayer:maskLayer atIndex:0];
而不是
self.view.layer.mask = maskLayer;
但是我的 self.view 丢失了 alpha 通道和 maskLayer 的动画不再工作
这是一个项目代码:https://www.dropbox.com/s/b94qcwxzoi23kwk/test_04092016.zip?dl=0
最简单的方法是让 UIButton
成为屏蔽视图的兄弟视图,而不是子视图。我意识到将按钮作为子视图可能是合乎逻辑的(特别是因为它看起来你的代码可能来自 UIViewController
子类),所以我会创建一个容器 UIView
来容纳所有的除了 mapCardsButton
之外的其他子视图并将掩码应用于此新视图。
假设您调用了新视图 maskedContainerView
,那么:
self.view
有两个子视图:maskedContainerView
和 mapCardsButton
maskedContainerView
拥有 self.view
曾经拥有的所有子视图,除了 mapCardsButton
maskedContainerView.layer.mask = maskLayer
.
你为什么不试试下面的方法呢?而不是以下堆栈:
• 掩码(视图)-> 按钮
使视图背景颜色清晰,在附加子视图中执行以下操作:
• 视图 -> 遮罩(子视图)、按钮
这样你会得到相同的视觉效果,但使用底视图作为容器。在代码中:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
[maskPath appendPath:[UIBezierPath bezierPathWithArcCenter:self.mapCardsButton.center
radius:self.mapCardsButton.frame.size.height/2.0f
startAngle:0.0f
endAngle:2.0f*M_PI
clockwise:NO]];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.path = maskPath.CGPath;
UIView *maskedView = [[UIView alloc] initWithFrame:self.view.bounds];
maskedView.mask = maskLayer;
self.view.backgroundColor = [UIColor clearColor];
[self.view addSubView:maskedView];
[self.view addSubView:self.mapCardsButton];
[maskedContainerView.layer insertSublayer:maskLayer atIndex:(unsigned)maskedContainerView.layer.sublayers.count];
在 'atIndex'
时重要性为 view.layer.sublayers.count 而不是 0
请收下!
基于您的代码。我不确定这是不是你想要的。
只需将按钮的 UIBezierPath 添加到您的 maskPath。
像这样的代码(基于您的代码)
const NSInteger kHoleSize = 100;
UIButton *mapCardsButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, kHoleSize, kHoleSize )];
[mapCardsButton setTitle:@"BUTTON" forState:UIControlStateNormal];
mapCardsButton.backgroundColor = [UIColor redColor];
[self.view addSubview:mapCardsButton];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:self.view.center
radius:kHoleSize/2.0f
startAngle:0.0f
endAngle:2.0f*M_PI
clockwise:NO];
UIBezierPath *buttonPath = [UIBezierPath bezierPathWithRect:mapCardsButton.frame];
[circlePath appendPath:buttonPath];
[maskPath appendPath:circlePath];
[maskPath setUsesEvenOddFillRule:YES];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = maskPath.CGPath;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.opacity = 0.9;
[self.view.layer addSublayer:maskLayer];
下面是对整个 UIView 应用蒙版的代码:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
[maskPath appendPath:[UIBezierPath bezierPathWithArcCenter:self.mapCardsButton.center
radius:self.mapCardsButton.frame.size.height/2.0f
startAngle:0.0f
endAngle:2.0f*M_PI
clockwise:NO]];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.path = maskPath.CGPath;
self.view.layer.mask = maskLayer;
问题是我想将上面的掩码应用到整个 UIView,除了一个特定的 UIButton(mapCardsButton),它也在同一个 UIView 上。 可以吗?
UPD:我试过了
[self.view.layer insertSublayer:maskLayer atIndex:0];
而不是
self.view.layer.mask = maskLayer;
但是我的 self.view 丢失了 alpha 通道和 maskLayer 的动画不再工作
这是一个项目代码:https://www.dropbox.com/s/b94qcwxzoi23kwk/test_04092016.zip?dl=0
最简单的方法是让 UIButton
成为屏蔽视图的兄弟视图,而不是子视图。我意识到将按钮作为子视图可能是合乎逻辑的(特别是因为它看起来你的代码可能来自 UIViewController
子类),所以我会创建一个容器 UIView
来容纳所有的除了 mapCardsButton
之外的其他子视图并将掩码应用于此新视图。
假设您调用了新视图 maskedContainerView
,那么:
self.view
有两个子视图:maskedContainerView
和mapCardsButton
maskedContainerView
拥有self.view
曾经拥有的所有子视图,除了mapCardsButton
maskedContainerView.layer.mask = maskLayer
.
你为什么不试试下面的方法呢?而不是以下堆栈:
• 掩码(视图)-> 按钮
使视图背景颜色清晰,在附加子视图中执行以下操作:
• 视图 -> 遮罩(子视图)、按钮
这样你会得到相同的视觉效果,但使用底视图作为容器。在代码中:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
[maskPath appendPath:[UIBezierPath bezierPathWithArcCenter:self.mapCardsButton.center
radius:self.mapCardsButton.frame.size.height/2.0f
startAngle:0.0f
endAngle:2.0f*M_PI
clockwise:NO]];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.path = maskPath.CGPath;
UIView *maskedView = [[UIView alloc] initWithFrame:self.view.bounds];
maskedView.mask = maskLayer;
self.view.backgroundColor = [UIColor clearColor];
[self.view addSubView:maskedView];
[self.view addSubView:self.mapCardsButton];
[maskedContainerView.layer insertSublayer:maskLayer atIndex:(unsigned)maskedContainerView.layer.sublayers.count];
在 'atIndex'
时重要性为 view.layer.sublayers.count 而不是 0基于您的代码。我不确定这是不是你想要的。
只需将按钮的 UIBezierPath 添加到您的 maskPath。 像这样的代码(基于您的代码)
const NSInteger kHoleSize = 100;
UIButton *mapCardsButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, kHoleSize, kHoleSize )];
[mapCardsButton setTitle:@"BUTTON" forState:UIControlStateNormal];
mapCardsButton.backgroundColor = [UIColor redColor];
[self.view addSubview:mapCardsButton];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:self.view.center
radius:kHoleSize/2.0f
startAngle:0.0f
endAngle:2.0f*M_PI
clockwise:NO];
UIBezierPath *buttonPath = [UIBezierPath bezierPathWithRect:mapCardsButton.frame];
[circlePath appendPath:buttonPath];
[maskPath appendPath:circlePath];
[maskPath setUsesEvenOddFillRule:YES];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = maskPath.CGPath;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.opacity = 0.9;
[self.view.layer addSublayer:maskLayer];