仅可见视图动画

Posted

技术标签:

【中文标题】仅可见视图动画【英文标题】:Only Visible View Animation 【发布时间】:2015-06-29 19:45:56 【问题描述】:

我有以下实现。每个视图都有动画,但我的问题是所有动画都运行,无论可见或不可见。我只希望当前看到(活动)的视图动画作品,其他视图动画被禁用,除非用户滚动它。

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view

    if (view == nil)
        if(index==0)
        
            view=[[UIImageView alloc]initWithFrame:CGRectMake(30, 30, 600, 600)];
            ((UIImageView *)view).animationImages=[NSArray arrayWithObjects:[UIImage imageNamed:@"Walking-1.png"],
                                 [UIImage imageNamed:@"Walking-2.png"],
                                 [UIImage imageNamed:@"Walking-3.png"],
                                 [UIImage imageNamed:@"Walking-4.png"],
                                 [UIImage imageNamed:@"Walking-5.png"],nil];

            ((UIImageView *)view).animationDuration = 1.5;
            [((UIImageView *)view) startAnimating];
        

        else if(index==1)
        
            view=[[UIImageView alloc]initWithFrame:CGRectMake(30, 30, 600, 600)];
            ((UIImageView *)view).animationImages=[NSArray arrayWithObjects:[UIImage imageNamed:@"Biking-1.png"],
                              [UIImage imageNamed:@"Biking-2.png"],
                              [UIImage imageNamed:@"Biking-3.png"],
                              [UIImage imageNamed:@"Biking-4.png"],                                                   
                              [UIImage imageNamed:@"Biking-5.png"],nil];

            ((UIImageView *)view).animationDuration = 1.5;
            [((UIImageView *)view) startAnimating];
        

        view.contentMode = UIViewContentModeCenter;
        [view.layer setMasksToBounds:YES];
    
    return view;

【问题讨论】:

【参考方案1】:

iCarouselDelegate 有一个方法carouselCurrentItemIndexDidChange 你应该在那里停止/开始你的动画,但不是在数据源方法中。因此,将所有动画保存到索引等于项目索引的数组中,并使用carouselCurrentItemIndexDidChange 中轮播的currentItemIndex 属性来启动适当的动画。您需要将之前的索引存储在类中的某个位置,以便能够在开始新动画之前停止之前的动画。

    @import UIKit;

    @interface CarouselController: UIViewController
    @property(nonatomic, readonly) NSArray *carouselItems;
    @property(nonatomic, assign) NSInteger lastItemIndex;
    @end

    @implementation CarouselController

    - (instancetype)init 
    self = [super init];

    if (self) 
        [self initializeCarouselContent];
    

    return self;


- (instancetype)initWithCoder:(NSCoder *)aDecoder 
    self = [super initWithCoder:aDecoder];

    if (self) 
        [self initializeCarouselContent];
    

    return self;


- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) 
        [self initializeCarouselContent];
    

    return self;


- (void)initializeCarouselContent 
    self.lastItemIndex = 0;
    _carouselItems = @[[CarouselController activityAnimationView: @"Walking"], [CarouselController activityAnimationView: @"Biking"]];

    UIImageView *currentAnimation = self.carouselItems[self.lastItemIndex];
    [currentAnimation startAnimating];


    + (UIImageView *)activityAnimationView:(NSString *)activity 
        UIImageView *result = [[UIImageView alloc]initWithFrame:CGRectMake(30, 30, 600, 600)];

        NSMutableArray *activityImages = [[NSMutableArray alloc] init];
        for (int activityIndex = 1; activityIndex <= 5; activityIndex ++) 
            NSString *imageName = [NSString stringWithFormat:@"%@-%i.png", activity, activityIndex];
            [activityImages addObject:[UIImage imageNamed:imageName]];
        
        result.animationImages = activityImages;
        result.animationDuration = 1.5;

        result.contentMode = UIViewContentModeCenter;
        [result.layer setMasksToBounds:YES];

        return result;
    


   - (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel  
        return [_carouselItems count];
     

    - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *) view

        if (view == nil)
            view = self.carouselItems[index];
        

        return view;
    

    - (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel 
        if (carousel.currentItemIndex != self.lastItemIndex) 
            UIImageView *currentAnimation = self.carouselItems[self.lastItemIndex];
            [currentAnimation stopAnimating];

            self.lastItemIndex = carousel.currentItemIndex;

            currentAnimation = self.carouselItems[self.lastItemIndex];
            [currentAnimation startAnimating];
        
    

    @end

【讨论】:

以上是关于仅可见视图动画的主要内容,如果未能解决你的问题,请参考以下文章

我想在setVisibility上制作动画视图,但它仅适用于第一次

Android ListView 项目动画 - 仅动画第一个可见项目

使用动画将视图的可见性从消失变为可见

共享元素过渡 - 仅对共享视图的可见部分进行动画处理

Adobe Animate CC Javascript - 每次可见时启动动画

Android动画问题——可见性变化比动画快