使用UIViewAnimation实现Gif

需求描述:
APP主页右上角的图标显示音乐的播放状态(暂停或者播放), 并且这个图标带一个点击事件, 除了主页, 其他的多个页面都用到这个播放动画(Class A).
使用UIViewAnimation实现Gif_第1张图片

分析:
显然,这是一个app**全局**的状态, 它的应用模型是:
一个类A, 有多个对象, 每个对象都对应一个点击事件. 但是这个类却具有一个”全局”的属性,能同时应用于多个对象.
所以, 可以考虑使用通知, 但不能用单例, 因为单例的点击事件也是”全局的”,与需求不符合.

我的解决方法:
通知+类A使用static变量记住播放状态
具体实现:
(1)在A的.m文件里, 使用静态变量记住通知里最新的状态(这样, 就算是在发送通知以后, 才建立的新对象, 也能利用此静态变量, 确定app中原有的状态);
(2)在视图A.m 中的init方法, 该类的对象都会注册通知;
(3)在视图A.m 中的init方法, 如果静态变量为Yes,则开启动画, 默认不开启.
(4)在视图A.h 中, 暴露一个发送通知的接口, 每次想要改变播放状态, 都只需调用此接口. 接着在.m文件实现此接口即可.
(为什么一定要用通知呢? 直接封装成一个开启/关闭动画的方法不可以吗?——–不行!! 只有通知, 才能通知多个对象, 如果使用普通方法, 只能是一对一,无法通知多个对象. )

注意事项:
①delloc时, 必须移除通知, 且UI的更新需要回到主线程;
②postNotification最好封装成该类的一个方法, 好处:该方法会通知到所有对象哦
③静态变量, 是在栈上的, 全局的

具体代码
.h文件

#import 

typedef NS_ENUM(NSInteger,JYMusicPlayerState){
    JYMusicPlayerStateStop = 0, //默认
    JYMusicPlayerStatePlaying = 1
};

typedef void(^JYMusicAnimationClickBlock)(void);

/**
 导航栏的播放动画
 */
@interface JYMusicPlayerStateView : UIView

@property (nonatomic, copy) JYMusicAnimationClickBlock clickBlock;


/**
 发送改变播放动画的状态的通知

 @param state JYMusicPlayerState状态值
 */
+(void)postMusicPlayAnimationStateNotificationWithState:(JYMusicPlayerState)state;
@end



.m文件

#import "JYMusicPlayerStateView.h"

static NSString * JYMusicPlayerNavStateChnageNotification = @"JYMusicPlayerNavStateChnageNotification";


@interface JYMusicPlayerStateView()

@property (nonatomic, strong) UIImageView *imgView;
@property (nonatomic, strong) NSMutableArray *imgNameArray;
@property (nonatomic, assign) BOOL isAnimated;

@end

@implementation JYMusicPlayerStateView

static JYMusicPlayerState my_app_play_state;

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        //注册通知
        //好处:多个self都会执行通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveStateChnageNotification:) name:JYMusicPlayerNavStateChnageNotification object:nil];

        _imgView = [[UIImageView alloc] initWithFrame:self.bounds];
        _imgView.userInteractionEnabled = YES;
        [_imgView setImage:[UIImage imageNamed:@"ios_00000"]];
        //动画数组
        _imgView.animationImages = [self transformToImagesByNames];
        _imgView.animationDuration = 1.0f;
        _imgView.animationRepeatCount = 0;
        [self addSubview:_imgView];


        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(doClick)];
        [self addGestureRecognizer:tap];

        //静态变量,栈上的.
        if (my_app_play_state == JYMusicPlayerStatePlaying) {
            [_imgView startAnimating];
        }


    }
    return self;
}



//发送通知
+(void)postMusicPlayAnimationStateNotificationWithState:(JYMusicPlayerState)state{

    [[NSNotificationCenter defaultCenter] postNotificationName:JYMusicPlayerNavStateChnageNotification object:@(state)];
}

//点击回调
-(void)doClick{
    if (self.clickBlock) {
        self.clickBlock();
    }
}



#pragma mark -- private method
//收到通知
-(void)didReceiveStateChnageNotification:(NSNotification *)notify{

    JYMusicPlayerState state = ((NSNumber *)notify.object).integerValue;
    my_app_play_state = state; //使用静态变量记住
    dispatch_async(dispatch_get_main_queue(), ^{

        if (state == JYMusicPlayerStatePlaying) {
            [_imgView startAnimating];

        } else {
            [_imgView stopAnimating];
        }
    });

//    [[NSUserDefaults standardUserDefaults] setObject:@(state) forKey:@"JYMusicPlayerStateSave"];

}



//返回image数组
-(NSArray<UIImage *> *)transformToImagesByNames{

    NSArray *names = @[@"ios_00000",@"ios_00001",@"ios_00002",@"ios_00003",@"ios_00004",@"ios_00005"];

    NSMutableArray *imgArr = [[NSMutableArray alloc]init];
    for (NSString *n in names) {
        [imgArr addObject:[UIImage imageNamed:n]];
    }
    return imgArr;
}


-(void)dealloc{

    [[NSNotificationCenter defaultCenter] removeObserver:self name:JYMusicPlayerNavStateChnageNotification object:nil];
}

@end

你可能感兴趣的:(iOS基础-笔记)