UIView框架改变时阴影图层未随其调整大小问题
哈哈这个坑我踩过好几次!问题出在阴影路径(shadowPath)没有随着视图frame的变化同步更新。
问题原因
当你调用dropShadow方法时,大概率是在里面设置了shadowPath(比如用当前视图的bounds生成了一个固定的路径)。这个路径是静态的——一旦创建就不会自动跟着视图的大小变化而改变。所以当你点击按钮修改shadow的frame时,视图本身的大小变了,但阴影还是按照最初的路径渲染,自然就跟不上了。
解决方案1:自定义View,自动同步阴影(最优雅)
让视图自己在布局变化时处理阴影更新,不用每次改frame都手动操作:
首先创建带阴影的自定义View:
class ShadowView: UIView { override func layoutSubviews() { super.layoutSubviews() // 每次布局变化(比如frame修改)时,同步更新阴影路径 layer.shadowPath = UIBezierPath(rect: bounds).cgPath } func dropShadow(scale: Bool = true) { layer.masksToBounds = false layer.shadowColor = UIColor.black.cgColor // 替换成你需要的阴影颜色 layer.shadowOpacity = 0.6 layer.shadowOffset = CGSize(width: 3, height: 3) layer.shadowRadius = 5 // 初始化时设置初始阴影路径 layer.shadowPath = UIBezierPath(rect: bounds).cgPath // 开启光栅化提升性能 layer.shouldRasterize = true layer.rasterizationScale = scale ? UIScreen.main.scale : 1 } }
然后在ViewController中使用这个自定义View:
class ViewController: UIViewController { var shadow: ShadowView! override func viewDidLoad() { super.viewDidLoad() shadow = ShadowView(frame: CGRect(x: 50, y: 50, width: 150, height: 150)) shadow.backgroundColor = .red shadow.dropShadow() self.view.addSubview(shadow) } @IBAction func btnActn(_ sender: Any) { self.shadow.frame = CGRect(x: 50, y: 50, width: 150, height: 50) // 啥都不用额外做,layoutSubviews会自动处理阴影更新 } }
解决方案2:修改frame后手动更新阴影路径
如果不想自定义View,也可以在每次修改frame后手动同步shadowPath,适合简单场景:
@IBAction func btnActn(_ sender: Any) { self.shadow.frame = CGRect(x: 50,y: 50,width: 150,height: 50) // 手动同步阴影路径到当前视图的bounds self.shadow.layer.shadowPath = UIBezierPath(rect: self.shadow.bounds).cgPath }
额外说明
为什么推荐用shadowPath?因为如果不设置它,系统会实时根据视图内容计算阴影范围,虽然能自动跟随变化,但性能开销会大很多(尤其是复杂视图)。用shadowPath可以明确告诉系统阴影的形状,既提升性能,又能精准控制阴影效果,唯一需要注意的就是要在布局变化时同步更新它。
内容的提问来源于stack exchange,提问作者Jishnu Raj T
相关产品推荐
相关产品推荐

