如何解决UIView的transitionCurlUp翻页动画中阴影圆角异常问题?
问题原因与解决方案
问题根源
确实是UIView翻页动画的工作机制导致的。UIKit的transitionCurlUp这类翻页动画是基于视图的原始矩形边界计算卷曲效果和阴影的,完全不会识别layer.cornerRadius设置的圆角裁剪。动画过程中,系统会把视图当作完整矩形渲染翻页光影,原本被圆角裁掉的区域会露出矩形视图的阴影,就出现了你看到的“阴影落在不可见元素上”的情况。
解决方案
方案一:用容器视图做裁剪
通过一个带圆角的容器视图来裁剪动画区域,让翻页效果被限制在圆角范围内:
class ViewController: UIViewController { @IBOutlet weak var containerView: UIView! { didSet { // 容器设置圆角并开启裁剪 containerView.layer.cornerRadius = 35 containerView.clipsToBounds = true // 创建目标视图并添加到容器 let buttonToBeCurled = UIView(frame: containerView.bounds) buttonToBeCurled.backgroundColor = .purple containerView.addSubview(buttonToBeCurled) // 添加点击手势到容器 let tap = UITapGestureRecognizer(target: self, action: #selector(curlTappedView)) containerView.addGestureRecognizer(tap) } } @objc func curlTappedView(_ gesture: UITapGestureRecognizer) { guard let tappedView = gesture.view else { return } UIView.transition(with: tappedView, duration: 3.0, options: [.transitionCurlUp], animations: {}) } }
方案二:改用CATransition实现翻页
直接操作图层动画,配合视图的裁剪属性,也能规避矩形阴影问题:
class ViewController: UIViewController { @IBOutlet weak var buttonToBeCurled: UIView! { didSet { let tap = UITapGestureRecognizer(target: self, action: #selector(curlTappedView)) buttonToBeCurled.addGestureRecognizer(tap) buttonToBeCurled.layer.cornerRadius = 35 buttonToBeCurled.backgroundColor = .purple buttonToBeCurled.clipsToBounds = true // 开启裁剪 } } @objc func curlTappedView(_ gesture: UITapGestureRecognizer) { guard let tappedView = gesture.view else { return } let transition = CATransition() transition.type = .pageCurl transition.subtype = .fromTop // 对应transitionCurlUp的翻页方向 transition.duration = 3.0 tappedView.layer.add(transition, forKey: "pageCurl") } }
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

