【问题标题】:Draw drop shadow only on one view below仅在下面的一个视图上绘制阴影
【发布时间】:2017-05-12 08:26:11
【问题描述】:

我有一个带有阴影的UIView。我希望在下面的单个视图上绘制阴影。问题是,下面的视图范围更小。

当前结果:

想要的结果:

注意:

用户通过拖入或拖出蓝色视图来动态更新屏幕。因此,解决方案不能是静态的。

有什么办法可以做到吗?

【问题讨论】:

  • 是否可以将两个视图(一个带有阴影,一个带有阴影)添加到一个视图中,然后将其遮罩为您想要的形状?
  • 如何定义掩码?另外,看看带阴影的视图实际上比下面那个大,所以我不能使用下面视图的边界作为蒙版,对吧?
  • 拖动的蓝色框需要在蒙版之外可见,并且只将其阴影投射到灰色框上?

标签: ios swift uiview shadow


【解决方案1】:

试试这个:

  1. 灰色视图:设置 cliptobounds = true
  2. 蓝色视图不应该是灰色视图的子视图,并且没有阴影。
  3. 在灰色视图中创建一个子视图,它看起来与蓝色视图完全相同,为此子视图设置阴影。

【讨论】:

  • 这在动态更新视图的 UI 时似乎相当不方便。我没有把它放在我的帖子里,对不起,更新了。
  • 有什么不方便的?您只需将 4 个约束从子视图添加到蓝色视图,它将坚持使用蓝色视图。
  • 哦,好的,我明白了。会试试的。
  • 不错的方法。谢谢!
【解决方案2】:
  1. 创建支架视图。
  2. 创建两个形状:蓝色框和灰色框。
  3. 将用于两个框的路径组合起来,创建第三个形状,用于遮盖支架视图。

UIView * background = [UIView new];
background.frame = self.view.bounds;
background.backgroundColor = [self colourForHex:@"#F5F5F5" andAlpha:1.0f];
[self.view addSubview:background];

UIView * holder = [UIView new];
holder.frame = CGRectMake((w-300)/2, (h-300)/2, 300, 300);
[background addSubview:holder];

UIBezierPath * boxPath = [UIBezierPath bezierPath];
[boxPath moveToPoint:CGPointMake(0, 0)];
[boxPath addLineToPoint:CGPointMake(0, 100)];
[boxPath addLineToPoint:CGPointMake(200, 100)];
[boxPath addLineToPoint:CGPointMake(200, 0)];
[boxPath closePath];

UIBezierPath * castPath = [UIBezierPath bezierPath];
[castPath moveToPoint:CGPointMake(10, 100)];
[castPath addLineToPoint:CGPointMake(0, 200)];
[castPath addLineToPoint:CGPointMake(200, 200)];
[castPath addLineToPoint:CGPointMake(190, 100)];
[castPath closePath];

CAShapeLayer * boxShape = [CAShapeLayer layer];
boxShape.path = boxPath.CGPath;
boxShape.fillColor = [self colourForHex:@"#1A0F53" andAlpha:1.0f].CGColor;
boxShape.shadowColor = [UIColor blackColor].CGColor;
boxShape.shadowOffset = CGSizeMake(5, 5);
boxShape.shadowRadius = 2.0f;
boxShape.shadowOpacity = 0.5f;
[holder.layer addSublayer:boxShape];

CAShapeLayer * castShape = [CAShapeLayer layer];
castShape.path = castPath.CGPath;
castShape.fillColor = [self colourForHex:@"#D8D8D8" andAlpha:1.0f].CGColor;
[holder.layer insertSublayer:castShape below:boxShape];

UIBezierPath * maskPath = [UIBezierPath bezierPath];
[maskPath appendPath:boxPath];
[maskPath appendPath:castPath];

CAShapeLayer * maskShape = [CAShapeLayer layer];
maskShape.path = maskPath.CGPath;
[holder.layer setMask:maskShape];

根据评论编辑:要添加 gif 中显示的动画,您可以将 UIPanGestureRecogniser 添加到视图并在用户滑动时偏移(原始要求),或者,在上面,我添加了一些类似这样的代码:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{

[UIView animateWithDuration:0.5f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     boxShape.transform = CATransform3DMakeTranslation(100, 0, 0);
                 }
                 completion:^(BOOL finished){
                 }];
            });

【讨论】:

  • 所以,我正在尝试重现您在上面的 gif 中显示的内容。你能分享你的项目吗?
  • 谢谢,我不是指动画本身,而是整个代码导致我很难让它工作。
  • 你在哪些方面苦苦挣扎?如果你愿意,可以在聊天中联系我。
  • 事实上这已经不重要了,因为我选择了LuanLai给出的解决方案。我真的不知道问题是什么。我从未使用过路径或形状。我基本上将您的代码翻译成 Swift,但它只显示一个蓝色矩形。但是,如果您可以将项目上传到 github 或类似的东西上,我也可以查看您的解决方案,也许会改变主意;)
  • 啊,好吧,没有项目可以粘在git上,我专门为你的问题写了上面的代码。
猜你喜欢
  • 2013-06-08
  • 2013-03-20
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 2012-01-09
相关资源
最近更新 更多