【问题标题】:Retrigger CABasicAnimation with NSThread in iOS在 iOS 中使用 NSThread 重新触发 CABasicAnimation
【发布时间】:2011-04-30 23:36:08
【问题描述】:

我正在破解这个核心动画示例: https://github.com/joericioppo/Shape_05

我想重新触发动画以响应 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

【问题讨论】:

    标签: objective-c ios core-animation cabasicanimation


    【解决方案1】:

    在另一个谷歌拖网之后确定: 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
    

    【讨论】:

      猜你喜欢
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多