向我的UIView添加投影的最佳方法是什么

Wez*_*Wez 103 shadow uiview ios cliptobounds

我试图为彼此叠加的视图添加投影,视图崩溃允许其他视图中的内容被看到,在这种情况下我想保持view.clipsToBounds开启,以便当视图崩溃时,他们的内容被剪裁.

这似乎使我很难向图层添加阴影,因为当我打开clipsToBounds阴影时也会被剪裁.

我一直试图操纵view.frameview.bounds为了向框架添加一个投影,但允许边界足够大以包含它,但是我没有运气.

这是我用来添加阴影的代码(这只适用于clipsToBoundsOFF,如图所示)

view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
Run Code Online (Sandbox Code Playgroud)

以下是应用于最轻的灰色层的阴影的屏幕截图.希望这能让我知道如果clipsToBounds关闭,我的内容将如何重叠.

影子应用.

如何为我添加阴影UIView并保持剪辑内容?

编辑:只是想补充说我还使用了带阴影的背景图像,这确实很有效,但是我仍然想知道最好的编码解决方案.

pkl*_*luz 273

试试这个:

UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
view.layer.masksToBounds = NO;
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
view.layer.shadowOpacity = 0.5f;
view.layer.shadowPath = shadowPath.CGPath;
Run Code Online (Sandbox Code Playgroud)

首先:UIBezierPath使用shadowPath至关重要.如果您不使用它,您可能一开始可能不会注意到差异,但敏锐的眼睛会观察到在旋转设备和/或类似事件期间发生的某种延迟.这是一项重要的性能调整.

关于你的问题:重要的是view.layer.masksToBounds = NO.它禁用了视图层的子层的剪切,这些子层比视图的边界延伸得更远.

对于那些想知道masksToBounds(在图层上)和视图自身clipToBounds属性之间的区别的人:实际上并没有.切换一个会对另一个产生影响.只是一个不同的抽象层次.


Swift 2.2:

override func layoutSubviews()
{
    super.layoutSubviews()

    let shadowPath = UIBezierPath(rect: bounds)
    layer.masksToBounds = false
    layer.shadowColor = UIColor.blackColor().CGColor
    layer.shadowOffset = CGSizeMake(0.0, 5.0)
    layer.shadowOpacity = 0.5
    layer.shadowPath = shadowPath.CGPath
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

override func layoutSubviews()
{
    super.layoutSubviews()

    let shadowPath = UIBezierPath(rect: bounds)
    layer.masksToBounds = false
    layer.shadowColor = UIColor.black.cgColor
    layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
    layer.shadowOpacity = 0.5
    layer.shadowPath = shadowPath.cgPath
}
Run Code Online (Sandbox Code Playgroud)

  • @JohnErck试试这个:`UIBezierPath*shadowPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:5.0];`.未经测试但应该产生您想要的结果. (6认同)

Bar*_*uik 64

Wasabii在Swift 2.3中的回答:

let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.blackColor().CGColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.CGPath
Run Code Online (Sandbox Code Playgroud)

在Swift 3/4中:

let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.cgPath
Run Code Online (Sandbox Code Playgroud)

如果您正在使用AutoLayout,请将此代码放在layoutSubviews()中.

  • 感谢您注意`layoutSubviews` (11认同)

ser*_*gio 13

诀窍是正确定义masksToBounds视图层的属性:

view.layer.masksToBounds = NO;
Run Code Online (Sandbox Code Playgroud)

它应该工作.

(来源)


Chr*_*ell 13

您可以为UIView创建扩展以在设计编辑器中访问这些值

设计编辑器中的阴影选项

extension UIView{

    @IBInspectable var shadowOffset: CGSize{
        get{
            return self.layer.shadowOffset
        }
        set{
            self.layer.shadowOffset = newValue
        }
    }

    @IBInspectable var shadowColor: UIColor{
        get{
            return UIColor(cgColor: self.layer.shadowColor!)
        }
        set{
            self.layer.shadowColor = newValue.cgColor
        }
    }

    @IBInspectable var shadowRadius: CGFloat{
        get{
            return self.layer.shadowRadius
        }
        set{
            self.layer.shadowRadius = newValue
        }
    }

    @IBInspectable var shadowOpacity: Float{
        get{
            return self.layer.shadowOpacity
        }
        set{
            self.layer.shadowOpacity = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你想进行实时预览(在界面构建器中),你可以在这里找到一篇关于它的好文章https://spin.atomicobject.com/2017/07/18/swift-interface-builder/ (2认同)

pal*_*avi 7

您也可以从故事板为视图设置阴影

在此输入图像描述