gpt4 book ai didi

swift - For循环覆盖动画

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

我试图每秒在屏幕上创建一条新的动画线。每一秒我都会得到一条新线,但它会覆盖旧线。我不知道为什么,但这可能是我忽略的愚蠢行为。这是我的代码:

func repeatThis() {
for x in 1...10 {
let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), Int64(x) * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
var topLinePatha: UIBezierPath {
return UIBezierPath(rect: CGRect(x: 0, y: 0 + (x * 10), width: 1, height: 10))
}

var topLinePathb: UIBezierPath {
return UIBezierPath(rect: CGRect(x: 0, y: 0 + (x * 10), width: Int(UIScreen.mainScreen().bounds.width), height: 10))
}

let expAnimation: CABasicAnimation = CABasicAnimation(keyPath: "path")
expAnimation.fromValue = topLinePatha.CGPath
expAnimation.toValue = topLinePathb.CGPath
expAnimation.duration = self.animationTime
expAnimation.fillMode = kCAFillModeForwards
expAnimation.removedOnCompletion = false
self.addAnimation(expAnimation, forKey: nil)
print(x)
}
}
}

感谢帮助

编辑 1:

这是我在动画计时方面遇到的一个问题,基本上动画会相互覆盖:

func repeatThis() {
var runningPath = UIBezierPath()

for x in 0...10 {
delay(Double(x) / 10) {
let topLineStartPath = UIBezierPath(rect: CGRect(x: 0, y: x * 10, width: 1, height: 10))
let topLineEndPath = UIBezierPath(rect: CGRect(x: 0, y: x * 10, width: Int(self.bounds.width), height: 10))

let fullStartPath = runningPath.copy() as! UIBezierPath
fullStartPath.appendPath(topLineStartPath)
let fullEndPath = runningPath.copy() as! UIBezierPath
fullEndPath.appendPath(topLineEndPath)

let expAnimation: CABasicAnimation = CABasicAnimation(keyPath: "path")
expAnimation.fromValue = fullStartPath.CGPath
expAnimation.toValue = fullEndPath.CGPath
expAnimation.duration = self.animationTime
expAnimation.fillMode = kCAFillModeForwards
expAnimation.removedOnCompletion = false
self.addAnimation(expAnimation, forKey: nil)
print(x)

runningPath = fullEndPath
}
}
}

func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}

最佳答案

每次您制作动画时,您的代码都会替换 CAShapeLayer 的路径,因此对于您制作动画的每一“行”,您都会丢失过去的行。

要显示多行,您可以:

  1. 使用方法UIBezierPath.appendPathCAShapeLayer 的路径添加多个子路径,每行一个。 .
  2. 使用多个 CAShapeLayer,每行一个。

这是备选方案 #1,与您当前的代码相比变化较小。这是一个独立的示例,您可以将其添加到名为 ViewController 的 View Controller 中的新 iOS 项目中。

import UIKit

class MyShapeLayer: CAShapeLayer {
var animationTime: NSTimeInterval = 0.75

func repeatThis() {
// Keep track of the path so far
var runningPath = UIBezierPath()

for x in 1...10 {
let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), Int64(x) * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
// We will add a rectangular subpath onto runningPath.
// It will be animated starting with:
let topLineStartPath = UIBezierPath(rect: CGRect(x: 0, y: x * 10, width: 1, height: 10))
// and ending with:
let topLineEndPath = UIBezierPath(rect: CGRect(x: 0, y: x * 10, width: Int(self.bounds.width), height: 10))

// Copy the running path, and add the starting and ending subpaths onto it
let fullStartPath = runningPath.copy() as! UIBezierPath
fullStartPath.appendPath(topLineStartPath)
let fullEndPath = runningPath.copy() as! UIBezierPath
fullEndPath.appendPath(topLineEndPath)

// Animate from fullStartPath to fullEndPath
let expAnimation: CABasicAnimation = CABasicAnimation(keyPath: "path")
expAnimation.fromValue = fullStartPath.CGPath
expAnimation.toValue = fullEndPath.CGPath
expAnimation.duration = self.animationTime
expAnimation.fillMode = kCAFillModeForwards
expAnimation.removedOnCompletion = false
self.addAnimation(expAnimation, forKey: nil)
print(x)

// The next time through the loop, add on to this iteration's ending path
runningPath = fullEndPath
}
}
}
}

class MyView: UIView {
override class func layerClass() -> AnyClass {
return MyShapeLayer.self
}
}

class ViewController: UIViewController {
override func loadView() {
self.view = MyView()
self.view.backgroundColor = UIColor.whiteColor()
}

override func viewDidLoad() {
if let myShapeLayer = self.view.layer as? MyShapeLayer {
myShapeLayer.repeatThis()
}
}
}

结果:

Animated GIF of the resulting animation

这是执行备选方案 #2 的一种方法。我延长了 animationTime,这样您就可以看到每行的动画可以重叠。

class LineAtATimeView: UIView {
var animationTime = 1.25 // longer duration so line animations overlap

func repeatAddingLines() {
for x in 1...10 {
let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), Int64(x) * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
let newLayer = CAShapeLayer()
newLayer.frame = self.bounds
self.layer.addSublayer(newLayer)

let topLineStartPath = UIBezierPath(rect: CGRect(x: 0, y: x * 10, width: 1, height: 10))
let topLineEndPath = UIBezierPath(rect: CGRect(x: 0, y: x * 10, width: Int(self.bounds.width), height: 10))

let expAnimation: CABasicAnimation = CABasicAnimation(keyPath: "path")
expAnimation.fromValue = topLineStartPath.CGPath
expAnimation.toValue = topLineEndPath.CGPath
expAnimation.duration = self.animationTime
expAnimation.fillMode = kCAFillModeForwards
expAnimation.removedOnCompletion = false
newLayer.addAnimation(expAnimation, forKey: nil)
}
}
}
}

class ViewController2: UIViewController {
override func loadView() {
self.view = LineAtATimeView()
self.view.backgroundColor = UIColor.whiteColor()
}

override func viewDidLoad() {
if let v = self.view as? LineAtATimeView {
v.repeatAddingLines()
}
}
}

关于swift - For循环覆盖动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36297010/

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