我的视图有一个UIButton,它是通过将角半径设置为视图高度的一半而形成的。一切都很好,但当它的动画(旋转摆动),角半径似乎改变,变形丸的形状。当动画结束时,所有恢复正常:
正常外观:

动画外观(见角半径):

这方面的记录如下所示:
动画代码(Xamarin c#)看起来如下:
public static void Wiggle(UIView view, double duration = 0.1f, float repeatCount = 3.0f)
{
UIView.Animate(duration,
() => view.Transform = CGAffineTransform.MakeRotation((nfloat)(-5f * Math.PI / 180f)),
() =>
{
UIView.AnimateNotify(duration, 0.0f, UIViewAnimationOptions.Repeat | UIViewAnimationOptions.Autoreverse | UIViewAnimationOptions.AllowUserInteraction,
() =>
{
UIView.SetAnimationRepeatCount(repeatCount);
view.Transform = CGAffineTransform.MakeRotation((nfloat)(5f * Math.PI / 180f));
},
(animationFinished) =>
{
UIView.Animate(duration, 0, UIViewAnimationOptions.AllowUserInteraction,
() => { view.Transform = CGAffineTransform.MakeIdentity(); }, null);
});
});
}正如视频中所看到的,这种情况并不总是发生。有时药丸形状保持不变。它既发生在模拟器上,也发生在真实设备上。有什么线索吗?谢谢
发布于 2021-10-08 21:08:14
您没有显示"PillShape“代码,但我假设您是在LayoutSubviews()中”将角半径设置为视图高度的一半“
如果是这样的话,问题可能是当您旋转按钮时,它的高度正在改变,并且您不再具有正确的半径。
您最好使用图层动画,而不是旋转视图本身。
我不使用Xamarin / C#,所以这是基于目标C代码.希望它能让你上路。
这使用一个缓慢(0.5秒)动画,使它很容易看到半径不改变在旋转。点击按钮启动/停止动画:
using Foundation;
using System;
using UIKit;
using CoreAnimation;
using ObjCRuntime;
namespace QuickTestApp
{
public partial class ViewController : UIViewController
{
public WigglePillButton btn { get; private set; }
public bool isWiggling { get; private set; }
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
btn = new WigglePillButton();
btn.TranslatesAutoresizingMaskIntoConstraints = false;
btn.SetTitle("Testing", UIControlState.Normal);
btn.BackgroundColor = UIColor.SystemBlueColor;
View.AddSubview(btn);
// Get the parent view's layout
var margins = View.SafeAreaLayoutGuide;
btn.CenterXAnchor.ConstraintEqualTo(margins.CenterXAnchor).Active = true;
btn.CenterYAnchor.ConstraintEqualTo(margins.CenterYAnchor).Active = true;
btn.WidthAnchor.ConstraintEqualTo(120).Active = true;
btn.AddTarget(this, new Selector("ButtonClickAction:"), UIControlEvent.TouchUpInside);
isWiggling = false;
}
[Export("ButtonClickAction:")]
public void ButtonClickAction(UIButton sender)
{
if (isWiggling)
{
btn.StopAnim();
} else {
btn.StartAnim();
}
isWiggling = !isWiggling;
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
public class WigglePillButton : UIButton
{
public override void LayoutSubviews()
{
base.LayoutSubviews();
var maskingShapeLayer = new CAShapeLayer()
{
Path = UIBezierPath.FromRoundedRect(Bounds, 12).CGPath
};
Layer.Mask = maskingShapeLayer;
}
public void StartAnim()
{
AddAnimations();
}
public void StopAnim()
{
Layer.RemoveAllAnimations();
}
private void AddAnimations()
{
CATransaction.Begin();
Layer.AddAnimation(RotAnim(), "rot");
CATransaction.Commit();
}
private CAKeyFrameAnimation RotAnim()
{
CAKeyFrameAnimation animation = CAKeyFrameAnimation.FromKeyPath("transform.rotation.z");
double angle = 5f * Math.PI / 180f;
animation.Values = new[] { NSNumber.FromDouble(angle), NSNumber.FromDouble(-angle) };
animation.AutoReverses = true;
animation.Duration = 0.5;
animation.RepeatCount = float.PositiveInfinity;
return animation;
}
}
}https://stackoverflow.com/questions/69497412
复制相似问题