Xamarin开发胶囊形UIButton摇摆动画时圆角变形问题求助
问题原因
这个问题是UIKit动画渲染机制和圆角设置逻辑共同导致的:
- 你将圆角设为视图高度的1/2,如果圆角是在
ViewDidLoad等布局未完成的生命周期节点设置的,动画过程中如果触发了临时的Auto Layout重绘,视图高度发生临时变化时圆角不会同步更新,就会出现变形。 - UIView级别的动画会隐式触发视图的布局重计算,变换动画过程中layer的cornerRadius属性没有被纳入同步动画队列,导致渲染不同步。
- 概率性出现是因为只有动画触发时刚好赶上视图布局更新的时机才会出现异常。
解决方案
方案1:调整圆角设置时机(最易用)
不要在视图初始化或ViewDidLoad中设置圆角,改在ViewDidLayoutSubviews中设置,保证每次视图布局更新后圆角都会同步为当前高度的1/2:
public override void ViewDidLayoutSubviews() { base.ViewDidLayoutSubviews(); // 每次布局完成后更新圆角 targetButton.Layer.CornerRadius = targetButton.Bounds.Height / 2; targetButton.ClipsToBounds = true; }
方案2:改用Core Animation层动画(最稳定)
直接对layer做旋转属性动画,不会触发不必要的视图级布局重计算,避免渲染不同步问题,替换你的现有动画代码即可:
public static void Wiggle(UIView view, double duration = 0.1f, float repeatCount = 3.0f) { var rotateAnim = CABasicAnimation.FromKeyPath("transform.rotation"); rotateAnim.Duration = duration; rotateAnim.From = NSNumber.FromDouble(-5 * Math.PI / 180); rotateAnim.To = NSNumber.FromDouble(5 * Math.PI / 180); rotateAnim.AutoReverses = true; rotateAnim.RepeatCount = repeatCount; rotateAnim.RemovedOnCompletion = true; rotateAnim.FillMode = CAFillMode.Forwards; view.Layer.AddAnimation(rotateAnim, "wiggle_anim"); }
方案3:增加layer渲染优化配置
给目标按钮的layer增加栅格化配置,保证动画过程中渲染稳定性,可配合前两种方案使用:
targetButton.Layer.ShouldRasterize = true; targetButton.Layer.RasterizationScale = UIScreen.MainScreen.Scale; targetButton.Layer.MasksToBounds = true;
方案4:父容器托管圆角(兼容性最高)
给按钮套一层同等大小的透明父容器,把圆角和裁剪属性加在父容器上,按钮作为子控件四边对齐父容器,动画直接作用在按钮上即可,父容器的圆角不会受子控件变换的影响,完全避免变形问题。
内容的提问来源于stack exchange,提问作者Bart
相关产品推荐
相关产品推荐

