2011-04-30 78 views
2

我这个黑客的Core Animation例如: https://github.com/joericioppo/Shape_05重新触发CABasicAnimation与NSThread iOS中

我想重新触发动画响应NSThread。 NSLogs按预期显示,但动画本身不会触发,直到所有睡眠完成,即使它的方法已被验证被调用。我怎样才能每秒重新触发这个动画?

顺便说一句 - 这只是我正在研究的一个示例补丁,以便理解这个概念。我知道动画可以重复设定,但这不是我想要做的,因为各种原因。这里的代码,任何帮助将非常欢迎,谢谢。

#import <UIKit/UIKit.h> 
#import <QuartzCore/QuartzCore.h> 

@interface Shape_05ViewController : UIViewController { 

    CALayer      *rootLayer; 

    CAShapeLayer   *shapeLayer; 

    CGMutablePathRef  pentagonPath; 
    CGMutablePathRef  starPath; 

    int animationCount; 
    CABasicAnimation *animation; 

} 

-(void)startAnimation; 
-(void) viewDidLoad; 
-(void) startSequence; 
-(void) enactSequence; 

@end 

#import "Shape_05ViewController.h" 

@implementation Shape_05ViewController 


- (void)loadView 
{ 

    UIView *appView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    appView.backgroundColor = [UIColor blackColor]; 
    self.view = appView; 
    [appView release]; 
    rootLayer = [CALayer layer]; 
    rootLayer.frame = self.view.bounds; 
    [self.view.layer addSublayer:rootLayer]; 


    //Pentagon Path 

    pentagonPath = CGPathCreateMutable(); 
    CGPoint center = self.view.center; 
    CGPathMoveToPoint(pentagonPath, nil, center.x, center.y - 75.0); 

    for(int i = 1; i < 5; ++i) { 
     CGFloat x = - 75.0 * sinf(i * 2.0 * M_PI/5.0); 
     CGFloat y = - 75.0 * cosf(i * 2.0 * M_PI/5.0); 
     CGPathAddLineToPoint(pentagonPath, nil,center.x + x, center.y + y); 
    } 
    CGPathCloseSubpath(pentagonPath); //This seems to be fixed in 4.0 

    //Star Path 

    starPath = CGPathCreateMutable(); 
    center = self.view.center; 
    CGPathMoveToPoint(starPath, NULL, center.x, center.y + 75.0); 
    for(int i = 1; i < 5; ++i) { 
     CGFloat x = 75.0 * sinf(i * 4.0 * M_PI/5.0); 
     CGFloat y = 75.0 * cosf(i * 4.0 * M_PI/5.0); 
     CGPathAddLineToPoint(starPath, NULL, center.x + x, center.y + y); 
    }; 
    CGPathCloseSubpath(starPath); 


    //Create Shape 

    shapeLayer = [CAShapeLayer layer]; 
    shapeLayer.path = pentagonPath; 
    UIColor *fillColor = [UIColor colorWithWhite:0.9 alpha:1.0]; 
    shapeLayer.fillColor = fillColor.CGColor; 
    shapeLayer.fillRule = kCAFillRuleNonZero; 
    [rootLayer addSublayer:shapeLayer]; 

} 


-(void) viewDidLoad { 

    NSLog(@"viewDidLoad"); 
    animationCount = 0; 
    [NSThread detachNewThreadSelector:@selector(startSequence) toTarget:self withObject:nil]; 

} 

-(void) startSequence { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [self enactSequence]; 
    //[NSThread sleepForTimeInterval:100]; 

    [pool release]; 

} 
-(void) enactSequence { 
    NSLog(@"enactSequence"); 
    for(int i = 0; i < 4; i++) { 
     [NSThread sleepForTimeInterval:1]; 
     [self performSelector:@selector(startAnimation) withObject:nil]; 
     [rootLayer setNeedsDisplay]; 
     NSLog(@"%i", i); 
    }; 

} 


-(void)startAnimation 
{ 
    NSLog(@"startAnimation"); 

    animation = [CABasicAnimation animationWithKeyPath:@"path"]; 
    animation.duration = 0.25; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.repeatCount = 0; 
    animation.autoreverses = NO; 
    animation.fillMode = kCAFillModeForwards; 
    animation.removedOnCompletion = YES; 

    if((animationCount % 2) == 0) { 
     animation.fromValue = (id)pentagonPath; 
     animation.toValue = (id)starPath; 
    } else { 
     animation.fromValue = (id)starPath; 
     animation.toValue = (id)pentagonPath; 
    }; 


    [shapeLayer addAnimation:animation forKey:@"animatePath"]; 

    animationCount++; 

} 


- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
} 


- (void)dealloc 
{ 
    CGPathRelease(starPath); 
    CGPathRelease(pentagonPath); 
    [super dealloc]; 
} 


@end 

回答

0

确定后,另一个谷歌拖网: http://forums.macrumors.com/showthread.php?t=749518&highlight=cabasicanimation

我发现了这个所谓的NSTimer!这个网站的另一个搜索发现一些好的信息: How do I use NSTimer?

而关于在自己的线程运行的NSTimer: Keep an NSThread containing an NSTimer around indefinitely? (iPhone)

所以,现在我可以提供这种更新的代码示例,我希望可以给别人一个有用天。顺便说一句,我没有尝试过,但显然可以使用下列停止计时器:

[myTimer invalidate]; 
myTimer = nil; 

感谢所有在这里在这个网站,不仅在网络的最精美的设计,但角落也是一个完全的救星!

#import <UIKit/UIKit.h> 
    #import <QuartzCore/QuartzCore.h> 

    @interface Shape_05ViewController : UIViewController { 

     CALayer      *rootLayer; 

     CAShapeLayer   *shapeLayer; 

     CGMutablePathRef  pentagonPath; 
     CGMutablePathRef  starPath; 

     int animationCount; 
     CABasicAnimation *animation; 
     NSTimer *repeatingTimer; 

    } 

@property (assign, readwrite) NSTimer *repeatingTimer; 

    -(void) startAnimation: (NSTimer*)theTimer; 
    -(void) viewDidLoad; 
    -(void) startSequence; 

    @end 

#import "Shape_05ViewController.h" 

    @implementation Shape_05ViewController 

    @synthesize repeatingTimer; 


    - (void)loadView 
    { 

     UIView *appView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
     appView.backgroundColor = [UIColor blackColor]; 
     self.view = appView; 
     [appView release]; 
     rootLayer = [CALayer layer]; 
     rootLayer.frame = self.view.bounds; 
     [self.view.layer addSublayer:rootLayer]; 


     //Pentagon Path 

     pentagonPath = CGPathCreateMutable(); 
     CGPoint center = self.view.center; 
     CGPathMoveToPoint(pentagonPath, nil, center.x, center.y - 75.0); 

     for(int i = 1; i < 5; ++i) { 
      CGFloat x = - 75.0 * sinf(i * 2.0 * M_PI/5.0); 
      CGFloat y = - 75.0 * cosf(i * 2.0 * M_PI/5.0); 
      CGPathAddLineToPoint(pentagonPath, nil,center.x + x, center.y + y); 
     } 
     CGPathCloseSubpath(pentagonPath); //This seems to be fixed in 4.0 

     //Star Path 

     starPath = CGPathCreateMutable(); 
     center = self.view.center; 
     CGPathMoveToPoint(starPath, NULL, center.x, center.y + 75.0); 
     for(int i = 1; i < 5; ++i) { 
      CGFloat x = 75.0 * sinf(i * 4.0 * M_PI/5.0); 
      CGFloat y = 75.0 * cosf(i * 4.0 * M_PI/5.0); 
      CGPathAddLineToPoint(starPath, NULL, center.x + x, center.y + y); 
     }; 
     CGPathCloseSubpath(starPath); 


     //Create Shape 

     shapeLayer = [CAShapeLayer layer]; 
     shapeLayer.path = pentagonPath; 
     UIColor *fillColor = [UIColor colorWithWhite:0.9 alpha:1.0]; 
     shapeLayer.fillColor = fillColor.CGColor; 
     shapeLayer.fillRule = kCAFillRuleNonZero; 
     [rootLayer addSublayer:shapeLayer]; 

    } 


    -(void) viewDidLoad { 

     NSLog(@"viewDidLoad"); 
     animationCount = 0; 

     [NSThread detachNewThreadSelector:@selector(startSequence) toTarget:self withObject:nil]; 

    } 

    -(void) startSequence { 
     NSLog(@"startSequence"); 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

     NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 
                  target:self 
                 selector:@selector(startAnimation:) 
                 userInfo:nil 
                 repeats:YES]; 
     [[NSRunLoop currentRunLoop] run]; 
     self.repeatingTimer = timer; 
     [pool release]; 

    } 

-(void)startAnimation: (NSTimer*)theTimer { 

     NSLog(@"startAnimation"); 

     animation = [CABasicAnimation animationWithKeyPath:@"path"]; 
     animation.duration = 0.25; 
     animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
     animation.repeatCount = 0; 
     animation.autoreverses = NO; 
     animation.fillMode = kCAFillModeForwards; 
     animation.removedOnCompletion = NO; 

     if((animationCount % 2) == 0) { 
      animation.fromValue = (id)pentagonPath; 
      animation.toValue = (id)starPath; 
     } else { 
      animation.fromValue = (id)starPath; 
      animation.toValue = (id)pentagonPath; 
     }; 
     [shapeLayer addAnimation:animation forKey:@"animatePath"]; 
     animationCount++; 

    } 


    - (void)didReceiveMemoryWarning 
    { 
     [super didReceiveMemoryWarning]; 
    } 


    - (void)dealloc 
    { 
     CGPathRelease(starPath); 
     CGPathRelease(pentagonPath); 
     [super dealloc]; 
    } 

    @end