我有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
错误,而且我在过去几个小时里一直在关注这个问题。我可能错过了一段代码吗?或者我错过了什么?
答案 0 :(得分:2)
.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)