根据时间在iOS Swift中将UIBezierPath上的UIImageAnimate动画

问题描述 投票:0回答:1

我用UIBezierPath创建了无穷大的♾符号,并在同一路径上设置了太阳视图的动画。但我想根据路径上的时间设置太阳视图。太阳视线总是从UIBezierPath的起始点开始动画。

以下是我无法完成的任务:-每当用户进入应用程序时,我都需要根据时间在UIBezierPath上设置太阳视,并从该特定点开始制作动画。

class LineDraw: UIView
{

    var path: UIBezierPath!

    let circleLayer = CAShapeLayer()
    var circlePathSize:CGSize?
    let circleView = UIView()
    let sunImage = UIImageView()

    override init(frame: CGRect)
    {
        super.init(frame: frame)
//        self.backgroundColor = UIColor.white
    }

    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)

    }

    override func draw(_ rect: CGRect)   {
        let height = self.frame.height
        let width = self.frame.width
        let heightFactor = height/4
        let widthFactor = width/4

        path = UIBezierPath()
        path.lineWidth = 3.0

        path.move(to: CGPoint(x:widthFactor, y: heightFactor))
        path.addCurve(to: CGPoint(x:widthFactor * 3, y: heightFactor * 3), controlPoint1: CGPoint(x:widthFactor * 2, y: heightFactor), controlPoint2: CGPoint(x:widthFactor * 2, y: heightFactor * 3))

        path.move(to: CGPoint(x:widthFactor * 3, y: heightFactor * 3))
        path.addCurve(to: CGPoint(x:widthFactor * 3, y: heightFactor), controlPoint1: CGPoint(x:widthFactor * 4, y: heightFactor * 3), controlPoint2: CGPoint(x:widthFactor * 4, y: heightFactor))

        path.move(to: CGPoint(x:widthFactor * 3, y: heightFactor))
        path.addCurve(to: CGPoint(x:widthFactor, y: heightFactor * 3), controlPoint1: CGPoint(x:widthFactor * 2, y: heightFactor), controlPoint2: CGPoint(x:widthFactor * 2, y: heightFactor * 3))

        path.move(to: CGPoint(x:widthFactor, y: heightFactor * 3))
        path.addCurve(to: CGPoint(x:widthFactor, y: heightFactor), controlPoint1: CGPoint(x:0, y: heightFactor * 3), controlPoint2: CGPoint(x:0, y: heightFactor))

        UIColor.purple.setStroke()
        path.stroke()
        animateCircleOnPath()
    }
    func animateCircleOnPath() {
        let animation = CAKeyframeAnimation(keyPath: "position");
        animation.duration = 20.0
        animation.repeatCount = MAXFLOAT
        sunImage.frame.size = CGSize(width: 40, height: 40)
        animation.path = path.cgPath
        sunImage.image = #imageLiteral(resourceName: "Logo")
        self.addSubview(sunImage)
        sunImage.layer.add(animation, forKey: nil)
    }
}

当前输出

enter image description here

ios swift uibezierpath
1个回答
0
投票

有点不清楚,但似乎您需要做的就是修改CAKeyframeAnimation。尝试类似以下的内容:

let animation = CAKeyframeAnimation(keyPath: "position");
animation.duration = 24*60*60 // 24 hours
animation.timeOffset = {
    let date = Date() // Now
    let startDateComponents = Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day], from: Date()) // Describing components that will return start of this day
    let startDate = Calendar.autoupdatingCurrent.date(from: startDateComponents)!
    let endDate = date

    return endDate.timeIntervalSince(startDate)
}()

正如您所说:

Sun视图将在24小时内完成单循环。

我们将持续时间设置为24h animation.duration = 24*60*60。您应该注意,由于夏令时,一天可能有23个小时或25个小时。这是一个极端的情况,但可能值得考虑。因此可以通过使用animation.duration = todayEndDate.timeIntervalSince(todayStartDate)来改善持续时间。但是24小时应该现在就可以。

然后是>>

[每当用户输入应用程序时,我都需要在UIBezierPath上设置太阳视图根据时间,然后从该特定点开始制作动画。

[所有需要做的都是设置一个正确的timeOffset,如果我正确假设的话,它应该是当天的持续时间;因此在13:23,应该是13小时23分钟,具体取决于您的本地时间和日历。

这里最棘手的部分是“取决于您当地的时间和日历”。因此,同时生活在世界不同地区的2个人会看到太阳在不同位置的位置。我希望这是有道理的。因此,我们需要检索这一天开始的Date。因此,我们使用以下内容:

let startDateComponents = Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day], from: Date())
let startDate = Calendar.autoupdatingCurrent.date(from: startDateComponents)!

我们需要使用当前的Date并从中提取年,月和日(没有小时和分钟)。为此,我们需要根据谁的观点进行选择。为此,要使用带有CalendarTimeZoneautoupdatingCurrent就是设备正在使用的。

然后,我们使用相同的日历来构成Date背面,现在默认情况下应将小时,分钟,秒...设置为0,从今天开始就有效地返回。

当我们使用时间间隔timeIntervalSince减去两个日期(当前日期和这一天开始的日期)时,我们获得了timeOffset所需的持续时间。

我希望这一切都可以清除。

© www.soinside.com 2019 - 2024. All rights reserved.