Ios 使用Xamarin的CALayer自定义特性动画
我真的很沮丧,因为从上周开始,我一直在尝试用CoreAnimation在iOS上制作饼图(带有透明孔的圆弧段)的动画 目前,我正在使用带有路径属性的CAShapeLayer绘制ArcSegment。它看起来很棒,但我无法设置此属性的动画。 我想用CABasicAnimation设置层属性(如半径、分段等)的动画 有人能告诉我怎么解决这个问题吗? 多谢各位 问候 罗尼Ios 使用Xamarin的CALayer自定义特性动画,ios,xamarin,cashapelayer,Ios,Xamarin,Cashapelayer,我真的很沮丧,因为从上周开始,我一直在尝试用CoreAnimation在iOS上制作饼图(带有透明孔的圆弧段)的动画 目前,我正在使用带有路径属性的CAShapeLayer绘制ArcSegment。它看起来很棒,但我无法设置此属性的动画。 我想用CABasicAnimation设置层属性(如半径、分段等)的动画 有人能告诉我怎么解决这个问题吗? 多谢各位 问候 罗尼 公共类ArcSegmentLayer:CAShapeLayer{ 私有常量字符串StartAngleProperty=“Start
公共类ArcSegmentLayer:CAShapeLayer{
私有常量字符串StartAngleProperty=“StartAngle”;
私有常量字符串EndAngleProperty=“EndAngle”;
公共静态无效注册表属性(){
RegisterDynamicProperty(typeof(arcegmentlayer)、StartAngleProperty、typeof(float));
RegisterDynamicProperty(typeof(ArcSegmentLayer)、EndAngleProperty、typeof(float));
}
公共ArcSegmentLayer(){}
[导出(“initWithLayer:”)]
公共ArcSegmentLayer(ArcSegmentLayer层){
this.LineWidth=layer.LineWidth;
this.Frame=layer.Frame;
this.FillColor=layer.FillColor;
this.StrokeColor=layer.StrokeColor;
this.Segments=layer.Segments;
this.Margin=layer.Margin;
}
#区域属性
公共浮球{
获取{return ObjCProperties.GetFloatProperty(Handle,StartAngleProperty);}
设置{
SetFloatProperty(句柄、StartAngleProperty、值);
}
}
公共浮动端角{
get{return ObjCProperties.GetFloatProperty(句柄,EndAngleProperty);}
设置{
SetFloatProperty(句柄、EndAngleProperty、值);
}
}
公共九段{
获取{返回段;}
设置{
如果(段!=值){
段=值;
此.SetNeedsDisplay();
}
}
}
公共贷款保证金{
得到{
收益率;
}
设置{
如果(边距!=值){
保证金=价值;
此.SetNeedsDisplay();
}
}
}
#端区
[导出(“需要显示forkey:”)]
公共静态布尔需要显示forkey(NSString键){
return key==StartAngleProperty
||key==EndAngleProperty
||键==“边距”
||键==“段”
||键==“线宽”
||键==“StrokeColor”
||CALayer.NeedsDisplayForKey(键);
}
[导出(“显示”)]
公共覆盖无效显示(){
base.Display();
Console.WriteLine(此.EndAngle);
this.Path=CreateSegments().CGPath;
}
[导出(“actionForKey:”)]
公共覆盖NSObject ActionForKey(字符串eventKey){
/*
如果(eventKey==EndAngleProperty){
CABasicAnimation动画=CABasicAnimation.FromKeyPath(eventKey);
animation.TimingFunction=CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
animation.From=new NSNumber(this.EndAngle);//PresentationLayer.ValueForKey(new NSString(eventKey));
//animation.Duration=cattransition.1;
动画。持续时间=0;
返回动画;
}else if(eventKey==StartAngleProperty){
CABasicAnimation动画=CABasicAnimation.FromKeyPath(eventKey);
animation.TimingFunction=CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
animation.From=新的NSNumber(this.StartAngle);
动画。持续时间=0;
返回动画;
}*/
返回base.ActionForKey(eventKey);
}
私有UIBezierPath CreateSegments(){
var path=新的UIBezierPath();
nfloat片段大小=(nfloat)(360.0/(nfloat)this.Segments);
nfloat STARTSENGLE=0;
nfloat endSegAngle=起始节段+节段尺寸;
如果(this.Segments>1){
var fromSeg=(nint)((双)this.Segments)*this.StartAngle)/360.0;
var-toSeg=(nint)(((双)此.段)*此.端角)/360.0);
对于(var seg=0;seg=fromSeg&&seg 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");
}
}