2015-04-22 2 views
2

Я пытаюсь анимировать backgroundColor CALayer с помощью CAKeyFrameAnimation. Когда я делаю это с классическими цветами, он работает; Но с цветом, полученным от patternImage UIColor(patternImage:"imageName").CGColor, он вообще не работает.CAKeyFrameAnimation с цветом от patternImage

@IBAction func animFirstView(sender: AnyObject) 
{ 
    addAnim(view1, colors: [UIColor.blackColor().CGColor, UIColor.redColor().CGColor]) // THAT WORKS 

} 

@IBAction func animSecondView(sender: AnyObject) 
{ 

    var firstColor = UIColor(patternImage: UIImage(named:"stars1")!).CGColor; 
    addAnim(view2, 
     colors: [firstColor]); // THAT doesn't works at all :(
} 

func addAnim(view:UIView, colors:[CGColor]) 
{ 
    let anim = CAKeyframeAnimation(keyPath:"backgroundColor") 
      anim.values = colors; 
    anim.keyTimes = [0.0, 0.25, 0.5, 0.75, 1]; 
    anim.calculationMode = kCAAnimationDiscrete 
    anim.duration = 0.3; 
    anim.repeatCount = Float.infinity; 
    view.layer.addAnimation(anim, forKey: "backgroundColor"); 

} 

У кого-то есть идея?

Разве это невозможно сделать, или я делаю что-то неправильно?

тест случай «ошибка» https://github.com/lastMove/patternBugDemo

+0

Благодарим вас за отправку примера в github! Это дало мне кое-что для работы. – matt

ответ

1

Я не знаю, почему установка backgroundColor в цвет рисунка как часть ключевого кадра анимации не работает. Я решил эту проблему, имитируя my own existing example где я поставил contents как ключевой кадр анимации:

@IBAction func animSecondView(sender: AnyObject) 
{ 
    var firstColor = UIColor(patternImage: UIImage(named:"stars1")!) 
    var secondColor = UIColor(patternImage: UIImage(named:"stars2")!) 
    addAnim(view2, 
     colors: [firstColor, secondColor, firstColor, secondColor]); 
} 

func addAnim(view:UIView, colors:[UIColor]) 
{ 
    let anim = CAKeyframeAnimation(keyPath:"contents") 
    anim.values = colors.map { 
     col in 
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, 0) 
     col.setFill() 
     UIBezierPath(rect: view.bounds).fill() 
     let im = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     return im.CGImage 
    } 
    anim.keyTimes = [0.0, 0.25, 0.75, 1.0]; 
    anim.calculationMode = kCAAnimationDiscrete 
    anim.duration = 1; 
    anim.repeatCount = Float.infinity; 
    view.layer.addAnimation(anim, forKey: nil); 
} 

enter image description here

EDIT: Вот еще один обходной путь: продолжать использовать цвет слоя фона, но изменить его непосредственно, с таймер:

@IBOutlet weak var view2: UIView! 
var colors = [UIColor]() 
var timer : NSTimer! 
var second = false 

@IBAction func animSecondView(sender: AnyObject) 
{ 
    var firstColor = UIColor(patternImage: UIImage(named:"stars1")!) 
    var secondColor = UIColor(patternImage: UIImage(named:"stars2")!) 
    self.colors = [firstColor, secondColor] 
    if let timer = self.timer { 
     timer.invalidate() 
    } 
    self.timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "anim:", userInfo: nil, repeats: true) 
} 
func anim(t:NSTimer) { 
    view2.layer.backgroundColor = self.colors[self.second ? 1 : 0].CGColor 
    self.second = !self.second 
} 
+0

Большое спасибо за это. Но мне действительно нужно сделать это по цвету. В моем проекте я загружаю SVG в CAShapeLayer, и я могу легко поместить изображения образов в те фигуры с помощью shapeLayer.fillColor = UIColor (patternImage: "image"). CGColor. Теперь я хочу сделать то же самое с краткими изображениями, как gif. Так что я не думаю, что могу использовать свойство содержимого. Кроме того, если я добавлю еще один подслой с маской на основную панель, но это кажется очень тяжелым. Я обязательно создам bugReport и/или билет. – LastMove

+0

Я думаю, что вы совершенно ошибаетесь в отношении «тяжелого». Неоднократное изменение «backgroundColor» или многократное изменение «содержимого» (возможно, другого уровня) не более или менее работает в отношении сервера рендеринга! Я согласен с вашей идеей отчета об ошибке, но я думаю, вы должны просто пойти дальше и использовать это обходное решение, если мы не сможем найти другой путь. – matt

+0

То, что кажется мне тяжелым, - это не анимация. Это факт, чтобы каждый раз добавлять подуровень + маску. Я попробую применить обходное решение с заливом цвета. Преимущество fillColor заключается в том, что он заполняет только путь слоя. Поэтому я должен найти, как имитировать это с вашего пути. – LastMove

Смежные вопросы