熟悉iOS开发的同学可能都知道圆角视图加阴影
一直都是一件比较头疼的事情。
有两种常见的方式:
1.
只设置layer
的cornerRadius
, 不设置 layer
的maskToBounds
弊端就是设置当设置了maskToBounds = true
时阴影会失效。
2.
在圆角的UIView后面藏一个稍微小一些的视图,圆角的视图挡住后面的小视图, 设置后面的小视图的阴影即可。
弊端,需要根据圆角的大小去调试背后小视图的大小。
除了上面的两种方法外是否还有更好的方法去给圆角视图加阴影?
在iOS Core Animation: Advanced Techniques 一书中讲Shadow Clipping的时候有下面一段话和示意图。
layer’s shadow derives from the exact shape of its contents, not just the bounds and cornerRadius. To calculate the shape of the shadow, Core Animation looks at the backing image (as well as the sublayers, if there are any) and uses these to create a shadow that perfectly matches the shape of the layer
Shadow Clippinglayer的阴影并不像bounds 和 cornerRadius一样是固定的,而是由其具体的内容的形状而生成。
为了得到阴影的形状,Core Animation 会根据其内容来完美的适配阴影效果。
根据这个原理我们就有了方案3:
将需要圆角的视图包裹到一个同等大小的透明视图中,圆角的视图负责圆角,透明的视图负责添加阴影。
WeCom20210425-194442.png封装
方案3
确定后就开始做圆角阴影视图的封装:
针对于UIButton
的封装
class CornerShadowButton: UIView {
var childView: UIButton = UIButton()
override init(frame: CGRect) {
super.init(frame: frame)
configBaseUI()
}
private func configBaseUI() {
childView = UIButton()
addSubview(childView)
childView.frame = bounds
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
同理,UIImageView
,UIView
, UILabel
都可以用相似的方法封装。
但其实,并没有必要这样。。
下面本文的重点来了:
在Swift中可以通过泛型
写出很优美便捷
的代码。
/// 阴影圆角的视图
class CornerShadowView<T: UIView>: UIView {
var childView: T = T()
override init(frame: CGRect) {
super.init(frame: frame)
configBaseUI()
}
private func configBaseUI() {
childView = T()
addSubview(childView)
childView.frame = bounds
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
针对于UIButton类的使用:
// 设置泛型的具体类为 UIButton
let cornerShadowView = CornerShadowView<UIButton>(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
// UIButton的基本属性设置
cornerShadowView.childView.setTitle("Hi", for: .normal)
// UIButton的圆角属性设置 可以进行二次封装,略。
cornerShadowView.childView.backgroundColor = .red
cornerShadowView.childView.layer.cornerRadius = 50
cornerShadowView.childView.layer.masksToBounds = true
// 阴影设置 可以进行二次封装,略。
cornerShadowView.layer.shadowColor = UIColor.black.cgColor
cornerShadowView.layer.shadowOffset = .zero
cornerShadowView.layer.shadowRadius = 20
cornerShadowView.layer.shadowOpacity = 0.8
效果如下:
image.pngUIImageView
,UIView
, UILabel
同理,将泛型中的具体类替换即可。
网友评论