2011-04-30 55 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