gpt4 book ai didi

c# - 将 Swift 转换为 C# 以在 Xamarin 中使用

转载 作者:可可西里 更新时间:2023-11-01 00:56:22 25 4
gpt4 key购买 nike

我正在编写一个 Xamarin.iOS 应用程序,并找到了一些我想使用的加载微调器的 Swift 代码。所以我正在尝试将 Swift 代码转换为 C#。我希望这个问题没问题,因为我已经尝试转换此代码数小时了。这是 Swift 代码:

public class CircularProgressView: UIView {

public dynamic var progress: CGFloat = 0 {
didSet {
progressLayer.progress = progress
}
}

fileprivate var progressLayer: CircularProgressLayer {
return layer as! CircularProgressLayer
}

override public class var layerClass: AnyClass {
return CircularProgressLayer.self
}


override public func action(for layer: CALayer, forKey event: String) -> CAAction? {
if event == #keyPath(CircularProgressLayer.progress),
let action = action(for: layer, forKey: #keyPath(backgroundColor)) as? CAAnimation {

let animation = CABasicAnimation()
animation.keyPath = #keyPath(CircularProgressLayer.progress)
animation.fromValue = progressLayer.progress
animation.toValue = progress
animation.beginTime = action.beginTime
animation.duration = action.duration
animation.speed = action.speed
animation.timeOffset = action.timeOffset
animation.repeatCount = action.repeatCount
animation.repeatDuration = action.repeatDuration
animation.autoreverses = action.autoreverses
animation.fillMode = action.fillMode
animation.timingFunction = action.timingFunction
animation.delegate = action.delegate
self.layer.add(animation, forKey: #keyPath(CircularProgressLayer.progress))
}
return super.action(for: layer, forKey: event)
}
}

fileprivate class CircularProgressLayer: CALayer {
@NSManaged var progress: CGFloat
let startAngle: CGFloat = 1.5 * .pi
let twoPi: CGFloat = 2 * .pi
let halfPi: CGFloat = .pi / 2


override class func needsDisplay(forKey key: String) -> Bool {
if key == #keyPath(progress) {
return true
}
return super.needsDisplay(forKey: key)
}

override func draw(in ctx: CGContext) {
super.draw(in: ctx)

UIGraphicsPushContext(ctx)

//Light Grey
UIColor.lightGray.setStroke()

let center = CGPoint(x: bounds.midX, y: bounds.midY)
let strokeWidth: CGFloat = 4
let radius = (bounds.size.width / 2) - strokeWidth
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: twoPi, clockwise: true)
path.lineWidth = strokeWidth
path.stroke()


//Red
UIColor.red.setStroke()

let endAngle = (twoPi * progress) - halfPi
let pathProgress = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle , clockwise: true)
pathProgress.lineWidth = strokeWidth
pathProgress.lineCapStyle = .round
pathProgress.stroke()

UIGraphicsPopContext()
}
}

let circularProgress = CircularProgressView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
UIView.animate(withDuration: 2, delay: 0, options: .curveEaseInOut, animations: {
circularProgress.progress = 0.76
}, completion: nil)

这是我目前所拥有的:

public class CircularProgressView : UIView
{
// I doubt I made these properties correctly?

public float Progress
{
get
{
return ProgressLayer.Progress;
}
set
{
ProgressLayer.Progress = value;
}
}

public CircularProgressLayer ProgressLayer { get; set; }

public override Foundation.NSObject ActionForLayer(CALayer layer, string eventKey)
{
// I don't understand this part

return base.ActionForLayer(layer, eventKey);
}
}

public class CircularProgressLayer : CALayer
{
public float Progress { get; set; }
private nfloat startAngle = (nfloat)(1.5f * Math.PI);
private nfloat twoPi = (nfloat)(2 * Math.PI);
private double halfPi = Math.PI / 2;

public override bool NeedsDisplay
{
get
{
return base.NeedsDisplay;
}
}

public override void DrawInContext(CoreGraphics.CGContext ctx)
{
base.DrawInContext(ctx);

UIGraphics.PushContext(ctx);

UIColor.LightGray.SetStroke();

var center = new CGPoint(x: Bounds.GetMidX(), y: Bounds.GetMidY());
float strokeWidth = 4;
nfloat radius = (Bounds.Size.Width / 2) - strokeWidth;
var path = UIBezierPath.FromArc(center, radius: radius, startAngle: 0, endAngle: twoPi, clockwise: true);
path.LineWidth = strokeWidth;
path.Stroke();

UIColor.Red.SetStroke();

nfloat endAngle = (nfloat)((twoPi * Progress) - halfPi);
var pathProgress = UIBezierPath.FromArc(center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true);
pathProgress.LineWidth = strokeWidth;
pathProgress.LineCapStyle = CGLineCap.Round;
pathProgress.Stroke();

UIGraphics.PopContext();
}
}

有几个部分我不明白,比如这个:

if event == #keyPath(CircularProgressLayer.progress)

还有这个:

fileprivate var progressLayer: CircularProgressLayer {
return layer as! CircularProgressLayer
}

我非常擅长 C#,但不熟悉 Swift。我希望这个问题没问题,因为我已经尝试转换此代码数小时了。

最佳答案

更新:

我需要在 Xamarin.iOS 原型(prototype)中创建 @dynamic/NSManaged 并最终能够通过在运行时创建它们来完成此操作,请在此处查看我的评论:

和相关要点:

因此,虽然 Xamarin.iOS 不支持它们开箱即用,但您可以根据需要在运行时创建它们。

原文:

目前您无法使用 Xamarin.iOS 生成动态属性 (@dynamic/NSManaged),因此您发布的代码甚至无法运行如果转换。

问题:https://bugzilla.xamarin.com/show_bug.cgi?id=38823

如果手动构造 CAAction/CAAnimation 对象是满足您需求的有效选项,您可以查看 Xamarin.iOS CustomPropertyAnimation 示例应用程序:

关于c# - 将 Swift 转换为 C# 以在 Xamarin 中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47022108/

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