CoreAnimation:将动画对象传输到下一个UIViewController

时间:2013-03-16 00:48:26

标签: iphone ios objective-c core-animation

我目前正在使用这个核心动画; (iOS 5,ARC)

- (void)onTimer
{
    // build a view from our image
    UIImageView* flakeView = [[UIImageView alloc] initWithImage:flakeImage];

    // use the random() function to randomize up our flake attributes
    int startX = round(random() % 320);
    int endX = startX; //round(random() % 320);
    double scale = 1 / round(random() % 100) + 1.0;
    double speed = 1 / round(random() % 100) + 1.0;

    // set the flake start position
    flakeView.frame = CGRectMake(startX, -100.0, 25.0 * scale, 25.0 * scale);
    flakeView.alpha = 0.8;

    // put the flake in our main view
    [self.view addSubview:flakeView];
    [self.view sendSubviewToBack:flakeView];

    [UIView beginAnimations:nil context:(__bridge void*)flakeView];
    // set up how fast the flake will fall
    [UIView setAnimationDuration:10 * speed];

    // set the postion where flake will move to
    flakeView.frame = CGRectMake(endX, 500.0, 25.0 * scale, 25.0 * scale);

    // set a stop callback so we can cleanup the flake when it reaches the
    // end of its animation
    [UIView setAnimationDidStopSelector:@selector(onAnimationComplete:finished:context:)];
    [UIView setAnimationDelegate:self];
    [UIView commitAnimations];

}
- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {

    UIImageView *flakeView = (__bridge UIImageView*)context;
    [flakeView removeFromSuperview];
    flakeView = nil;
}

火;

[NSTimer scheduledTimerWithTimeInterval:(0.3) target:self selector:@selector(onTimer) userInfo:nil repeats:YES];

使用此代码,会有10张雪花落下来。

借助此代码和一些自定义视图过渡,我试图使导航操作流畅。问题是我无法找到将这些(动画)上下文转移到下一个UIViewController的正确方法,因此所有动画雪花将继续前进到他们离开的位置,以及下一个UIViewController的{​​{1}} 1}}会激发新的。

任何帮助和建议都会得到满足。

3 个答案:

答案 0 :(得分:0)

也许您可以将您的上下文放在此课程的私人扩展中 像:@property (nonatomic,weak)IBOutlet UIImageView*context;

答案 1 :(得分:0)

我怀疑您是否可以将动画视图传输到另一个视图控制器。我怀疑当你从超级视图中删除它时,它将终止任何动画。

编写跟踪数组中动画视图的代码可能会更好。在创建新视图控制器时,查询每个图像视图图层的presentationLayer并获取它的位置。然后从当前视图控制器中删除所有雪花视图,并将整个数组和位置数组传递给新视图控制器。然后在新视图控制器的viewDidLoad中,在之前的位置添加雪花视图数组,并启动它们动画到之前的结束位置,然后启动动画计时器以开始添加更多雪花。

答案 2 :(得分:0)

.h文件

@interface BeanManager : NSObject <UINavigationControllerDelegate>
{
    NSMutableDictionary *beanDictionary;
    UIViewController    *currentViewController;
    UIImage             *coffeebean;
    NSTimer             *beanTimer;
    NSInteger           contextTag;
    BOOL                isDebugging;
}

@property (nonatomic, retain) NSMutableDictionary   *beanDictionary;
@property (nonatomic, retain) UIViewController      *currentViewController;
@property (nonatomic) BOOL isDebugging;

+ (id)sharedManager;

- (void)invalidate;
- (void)validate;

@end

.m文件

+ (id)sharedManager {
    static BeanManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (id)init {
    if (self = [super init]) {
        coffeebean = [UIImage imageNamed:@"coffeebean"];

        // assign self as navigation controllers delegate
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        [appDelegate.navigationController setDelegate:self];

        self.currentViewController = appDelegate.navigationController.visibleViewController;

        beanDictionary = [[NSMutableDictionary alloc] init];

        NSLog(@"%@ : Allocating",[self class]);

        [self validate];
    }
    return self;
}

- (void)dealloc {
    if (isDebugging) {
        NSLog(@"%@: Deallocating", [self class]);
    }
}

#pragma mark - UINavigationController
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (isDebugging) {
        NSLog(@"%@: Pushing %d beans to new view",[self class], [[beanDictionary allKeys] count]);
    }
    for (UIImageView *animatingBeans in [beanDictionary allValues]) {
        [viewController.view addSubview:animatingBeans];
        [viewController.view sendSubviewToBack:animatingBeans];
    }

    self.currentViewController = viewController;
}

#pragma mark - Internals
- (void)validate
{
    beanTimer = [NSTimer scheduledTimerWithTimeInterval:(0.3) target:self selector:@selector(onTimerWithBlock) userInfo:nil repeats:YES];
}

- (void)invalidate
{
    [beanTimer invalidate];
}

- (void)onTimerWithBlock
{
    // build a view from our flake image
    UIImageView* beanView = [[UIImageView alloc] initWithImage:coffeebean];

    // use the random() function to randomize up our flake attributes
    int startX = round(random() % 320);
    int endX = startX; //round(random() % 320);
    double scale = 1 / round(random() % 100) + 1.0;
    double speed = 1 / round(random() % 100) + 1.0;

    // set the flake start position
    beanView.frame = CGRectMake(startX, -100.0, 25.0 * scale, 25.0 * scale);
    beanView.alpha = 0.8;
    beanView.tag = contextTag; 

    [beanDictionary setObject:beanView forKey:[NSString stringWithFormat:@"%d",contextTag]];

    if (contextTag > 1000) {
        contextTag = 0;
    }
    contextTag++;

    // put the flake in our main view
    [self.currentViewController.view addSubview:beanView];
    [self.currentViewController.view sendSubviewToBack:beanView];

    [UIView animateWithDuration:(speed * 10) animations:^{

        [beanView setFrame:CGRectMake(endX, 500.0, 25.0 * scale, 25.0 * scale)];

    } completion:^(BOOL finished) 
    {
        [beanDictionary removeObjectForKey:[NSString stringWithFormat:@"%d",beanView.tag]];
        if (isDebugging) {
            NSLog(@"%@: Dictionary Count %d",[self class], [[beanDictionary allKeys] count]);
        }
        [beanView removeFromSuperview];
    }];
}

这段代码似乎可以完成这项工作。到目前为止,我没有将它用作Singleton,但如果我将扩展此代码,它应该实现为单例,只是为了澄清。我使用的是NSDictionary而不是NSArray,它可以正常工作,我再次认为我可能会添加一些功能,所以我将其设为NSDictionary