gpt4 book ai didi

ios - 使用 Xamarin 的 CALayer 自定义属性动画

转载 作者:行者123 更新时间:2023-11-28 21:21:06 26 4
gpt4 key购买 nike

我真的很沮丧,因为自上周以来,我一直在尝试使用 CoreAnimation 在 iOS 上为饼图(带有透明孔的弧段)制作动画。

目前,我正在使用具有路径属性的 CAShapeLayer 绘制 ArcSegment。它看起来不错,但我无法为该属性设置动画。我想使用 CABasicAnimation 为 Layer-Property 设置动画,例如 Radius、Segments 等。

这里有没有人,谁能告诉我如何解决这个问题?谢谢。

问候罗尼

    public class ArcSegmentLayer : CAShapeLayer {
private const string StartAngleProperty = "StartAngle";
private const string EndAngleProperty = "EndAngle";

public static void RegisterProperties() {
ObjCProperties.RegisterDynamicProperty(typeof(ArcSegmentLayer), StartAngleProperty, typeof(float));
ObjCProperties.RegisterDynamicProperty(typeof(ArcSegmentLayer), EndAngleProperty, typeof(float));
}

public ArcSegmentLayer() { }

[Export("initWithLayer:")]
public ArcSegmentLayer(ArcSegmentLayer layer) {
this.LineWidth = layer.LineWidth;
this.Frame = layer.Frame;
this.FillColor = layer.FillColor;
this.StrokeColor = layer.StrokeColor;
this.Segments = layer.Segments;
this.Margin = layer.Margin;
}

#region Properties

public float StartAngle {
get { return ObjCProperties.GetFloatProperty(Handle, StartAngleProperty); }
set {
ObjCProperties.SetFloatProperty(Handle, StartAngleProperty, value);
}
}

public float EndAngle {
get { return ObjCProperties.GetFloatProperty(Handle, EndAngleProperty); }
set {
ObjCProperties.SetFloatProperty(Handle, EndAngleProperty, value);
}
}

public nint Segments {
get { return segments; }
set {
if (segments != value) {
segments = value;
this.SetNeedsDisplay();
}
}
}

public nfloat Margin {
get {
return margin;
}
set {
if (margin != value) {
margin = value;
this.SetNeedsDisplay();
}
}
}

#endregion

[Export("needsDisplayForKey:")]
public static bool NeedsDisplayForKey(NSString key) {
return key == StartAngleProperty
|| key == EndAngleProperty
|| key == "Margin"
|| key == "Segments"
|| key == "LineWidth"
|| key == "StrokeColor"
|| CALayer.NeedsDisplayForKey(key);
}

[Export("display")]
public override void Display() {
base.Display();

Console.WriteLine(this.EndAngle);

this.Path = CreateSegments().CGPath;
}

[Export("actionForKey:")]
public override NSObject ActionForKey(string eventKey) {
/*
if (eventKey == EndAngleProperty) {
CABasicAnimation animation = CABasicAnimation.FromKeyPath(eventKey);
animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
animation.From = new NSNumber(this.EndAngle); //PresentationLayer.ValueForKey(new NSString(eventKey));
//animation.Duration = CATransition. 1;
animation.Duration = 0;
return animation;
} else if (eventKey == StartAngleProperty) {
CABasicAnimation animation = CABasicAnimation.FromKeyPath(eventKey);
animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
animation.From = new NSNumber(this.StartAngle);
animation.Duration = 0;
return animation;
}*/
return base.ActionForKey(eventKey);
}

private UIBezierPath CreateSegments() {
var path = new UIBezierPath();

nfloat segmentSize = (nfloat)(360.0 / (nfloat)this.Segments);
nfloat startSegAngle = 0;
nfloat endSegAngle = startSegAngle + segmentSize;

if (this.Segments > 1) {
var fromSeg = (nint)((((double)this.Segments) * this.StartAngle) / 360.0);
var toSeg = (nint)((((double)this.Segments) * this.EndAngle) / 360.0);
for (var seg = 0; seg < this.Segments; seg++) {
var hiddenLayer = !(seg >= fromSeg && seg < toSeg);
if (!hiddenLayer) {
path.AppendPath(
this.CreateSegmentPath(
startSegAngle, endSegAngle - this.Margin));
}
startSegAngle += segmentSize;
endSegAngle += segmentSize;
}
} else if (this.Segments == 1) {
path.AppendPath(this.CreateSegmentPath(this.StartAngle, this.EndAngle));
}
return path;
}

private UIBezierPath CreateSegmentPath(nfloat startSegAngle, nfloat endSegAngle) {
var center = new CGPoint(x: this.Bounds.Width / 2f, y: this.Bounds.Height / 2f);
var radius = (nfloat)Math.Max(this.Bounds.Width, this.Bounds.Height) / 2f - this.LineWidth / 2f;

var path = UIBezierPath.FromArc(
center,
radius,
Deg2Rad(startSegAngle - 90f),
Deg2Rad(endSegAngle - 90f),
true);

path.MoveTo(center);
path.ClosePath();
path.Stroke();

return path;
}

private static nfloat Deg2Rad(nfloat value) {
return (nfloat)(floatPI / 180.0 * value);
}

private static readonly nfloat floatPI = (nfloat)Math.PI;

private nint segments;
private nfloat margin;
}

[DesignTimeVisible(true)]
public partial class ArcSegmentView : UIView {
public ArcSegmentView(IntPtr handle) : base(handle) {
this.strokeColor = UIColor.Black.CGColor;
}

#region Properties

[Export("StartAngle"), Browsable(true)]
public nfloat StartAngle {
get { return startAngle; }
set {
if (startAngle != value) {
startAngle = value;
((ArcSegmentLayer)this.Layer).StartAngle = (float)value;
this.SetNeedsDisplay();
}
}
}

[Export("EndAngle"), Browsable(true)]
public nfloat EndAngle {
get { return endAngle; }
set {
if (endAngle != value) {
endAngle = value;
((ArcSegmentLayer)this.Layer).EndAngle = (float)value;
this.SetNeedsDisplay();
}
}
}

[Export("Segments"), Browsable(true)]
public nint Segments {
get { return segments; }
set {
if (segments != value) {
segments = value;
((ArcSegmentLayer)this.Layer).Segments = value;
this.SetNeedsDisplay();
}
}
}

[Export("Margin"), Browsable(true)]
public nfloat Margin {
get { return margin; }
set {
if (margin != value) {
margin = value;
((ArcSegmentLayer)this.Layer).Margin = value;
this.SetNeedsDisplay();
}
}
}

[Export("LineWidth"), Browsable(true)]
public nfloat LineWidth {
get { return lineWidth; }
set {
if (lineWidth != value) {
lineWidth = value;
((ArcSegmentLayer)this.Layer).LineWidth = value;
this.SetNeedsDisplay();
}
}
}

[Export("StrokeColor"), Browsable(true)]
public CGColor StrokeColor {
get { return strokeColor; }
set {
if (StrokeColor != value) {
strokeColor = value;
((ArcSegmentLayer)this.Layer).StrokeColor = value;
//this.SetNeedsDisplay();
}
}
}

#endregion

[Export("layerClass")]
static Class LayerClass() {
return new Class(typeof(ArcSegmentLayer));
}

private nfloat lineWidth;
private nfloat margin;
private nint segments;
private nfloat startAngle;
private nfloat endAngle;
private CGColor strokeColor;
}

public partial class ViewController : UIViewController {
protected ViewController(IntPtr handle) : base(handle) { }

public override void ViewDidLoad() {
base.ViewDidLoad();

arcSegment.StartAngle = 45;
arcSegment.EndAngle = 90;
arcSegment.Margin = 2;
arcSegment.StrokeColor = UIColor.Red.CGColor;
arcSegment.Segments = 70;
arcSegment.LineWidth = 10;

CABasicAnimation animation = CABasicAnimation.FromKeyPath("EndAngle");
animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
animation.From = new NSNumber(45);
animation.To = new NSNumber(360);
animation.Duration = 10;

arcSegment.Layer.AddAnimation(animation, "EndAngle");
}
}

最佳答案

关于ios - 使用 Xamarin 的 CALayer 自定义属性动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39815542/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com