以编程方式创建的阴影不会显示

时间:2018-01-15 12:19:25

标签: ios swift

我有iOS应用程序,我有几个带阴影的视图(为方便起见,称为shadowView)。这是他们的成就:

        let shadowView = UIView(frame: .zero)
        self.addSubview(shadowView)
        shadowView.layer.shadowColor = UIColor.black.cgColor
        shadowView.layer.shadowOffset = CGSize(width: 0.5, height: 1.5)
        shadowView.layer.shadowOpacity = 0.15
        shadowView.layer.masksToBounds = false
        shadowView.layer.cornerRadius = 8
        shadowView.backgroundColor = .clear
        shadowView.layer.shadowRadius = 5.0
        shadowView.clipsToBounds = false
        shadowView.layer.shadowPath = UIBezierPath(roundedRect: shadowView.bounds, cornerRadius: 20).cgPath

然后将视图放在Snapkit的位置,但由于它不相关,我遗漏了部分代码。现在我没有显示我在这里制作的阴影。但是,如果我将backgroundColor属性设置为例如UIColor.yellow然后视图本身显示,但不显示阴影。

我还检查了阴影是否会被任何父视图切断,这似乎并非如此。

你可以看到它不是通常的clipsToBounds / masksToBounds错误,而且我在过去几个小时里一直在关注这个问题。我可能错过了一段代码吗?或者我错过了什么?

5 个答案:

答案 0 :(得分:2)

  1. 您的相框尺寸为.zero。为其指定一些有效的大小。

答案 1 :(得分:2)

为视图提供非零帧大小

let viewWidth =  //any

let viewHeight =  //any

let shadowView = UIView(frame: CGRect.init(x: 0, y: 0, width: viewWidth, height: viewHeight))

答案 2 :(得分:1)

试图澄清......

您正在设置.shadowPath,但根据您的代码,您将之前的设置为.shadowView并设置了其框架。因此,您创建的UIBezierPath框架为.zero - 并且永远不会更改。

您需要在视图控制器的viewDidLayoutSubviews中设置阴影路径,或者在自定义视图中覆盖layoutSubviews()

以下是一个可以在Playground页面中运行的简单示例:

import UIKit
import PlaygroundSupport

class TestViewController : UIViewController {

    let shadowView = UIView(frame: .zero)

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(shadowView)

        shadowView.layer.shadowColor = UIColor.black.cgColor
        shadowView.layer.shadowOpacity = 0.15
        shadowView.layer.cornerRadius = 8
        shadowView.backgroundColor = .clear


        // this would be handled by your use of SnapKit
        shadowView.translatesAutoresizingMaskIntoConstraints = false

        shadowView.topAnchor.constraint(equalTo: view.topAnchor, constant: 40.0).isActive = true
        shadowView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20.0).isActive = true
        shadowView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20.0).isActive = true

        shadowView.heightAnchor.constraint(equalToConstant: 100).isActive = true

    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        shadowView.layer.shadowPath = UIBezierPath(roundedRect: shadowView.bounds, cornerRadius: 20).cgPath
    }

}

let vc = TestViewController()
vc.view.backgroundColor = .white
PlaygroundPage.current.liveView = vc

答案 3 :(得分:0)

像其他同事所说,你的观点框架就是问题所在。

这是一个问题,因为您将图层的阴影路径设置为与当时的视图边界一样大.zero

我仍然明白,当自动布局引擎准备好布局视图时,您希望视图对其约束作出反应。然后,您可以采取两项措施来解决此问题:

1)您可以删除显式的shadowView.layer.shadowPath集,并将视图的颜色从清除更改为另一种颜色。这将使阴影遵循视图的形状,即使它发生变化,也会使用动态阴影路径。虽然这将解决问题,但有时它也会对动画和过渡期间的性能产生影响。

2)如果视图在屏幕上没有改变其大小,你可以在将shadowView添加为子视图后立即强制superView重新布局。

self.addSubview(shadowView)
self.setNeedsLayout()
self.layoutIfNeeded()

这样当你创建阴影路径时,边界不会为零,因为自动布局已经改变了视图的框架。

请注意,使用第二种解决方案时,您将看不到视图(颜色清晰),只看到它的阴影。

答案 4 :(得分:-1)

Swift 4

在视图控制器中添加此功能

func addShadow(myView: UIView?) {
    myView?.layer.shadowColor = UIColor.black.cgColor
    myView?.layer.shadowOffset = CGSize(width: 0, height:0)
    myView?.layer.shadowOpacity = 0.3
    myView?.layer.shadowRadius = 5
    myView?.layer.masksToBounds = false
    myView?.layer.cornerRadius = 12
}

并使用它:

let shadowView = UIView(frame: CGRect(x: 0, y: 0, width: yourWidth, height: yourHeight))
self.addShadow(shadowView)