iOS 模仿Pokemon Go主页的动画Menu

本文介绍了一款自定义iOS菜单栏组件YHCustomMenu的实现过程,包括点击事件、动画效果及图标颜色变化等内容。

YHCustomMenu:github地址


前言

那天我没事申请了个美国区的AppleID,下了个Pokemon Go,注册了个账号,然后进入官网,看到了这样一个菜单栏。


是不是很好看? 看完的我少女心爆棚啊~~~~

于是着手在iOS上实现,其实很简单。

主要是点击事件和动画的结合,动画中包含着图片的渲染 以及那个彩色的覆盖视图的移动动画。

附上我第一次做的效果图。直接用另一个View覆盖的,所以根本不是我想要的效果。


于是我换了种思路,我想是不是图片是固定的,经过渲染而得的不同颜色呢?

于是进行实践,又有了下面的效果图。


差不多了,其他需要按照需求优化即可。

正文

我的创作思路,我总共创建了两个自定义view,一个是Menu上的ButtonView,我管它叫YHCustomMenuView。主要由一条彩色线,一个图标,一个彩色覆盖视图组成。
另一个就是YHCustomMenu,是由多个YHCustomMenuView组成,有number和defaultIndex以及themeColorArr和iconImgArr四个参数,需要我们自己设置。
主要代码:
YHCustomMenuView.h
#import <UIKit/UIKit.h>

@interface YHCustomMenuView : UIView
//图标
@property (nonatomic, retain) UIImage *iconImg;
//整体颜色
@property (nonatomic, retain) UIColor *themeColor;
//图片上的icon
@property (nonatomic, retain) UIImageView *iconImgView;
@end


YHCustomMenuView.m
#import "YHCustomMenuView.h"
@interface YHCustomMenuView ()
//彩色覆盖视图
@property (nonatomic, retain) UIView *colorfulView;
//白色底图的彩色线条
@property (nonatomic, retain) UIView *lineView;

@end

@implementation YHCustomMenuView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self addAllSubViews];
    }
    return self;
}

//添加所有的子视图
- (void)addAllSubViews {
    //所有的frame基于父视图设计
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    
    self.lineView =[[UIView alloc] initWithFrame:CGRectMake(width-5,0, 5, height)];\
    
    self.iconImgView = [[UIImageView alloc] initWithFrame:CGRectMake(width * 0.35,height *0.35, width *0.3, width *0.3)];
    self.iconImgView.userInteractionEnabled = YES;
    
    self.colorfulView = [[UIView alloc] initWithFrame:CGRectMake(-width, 0,width , height)];
    
    [self addSubview:self.lineView];
    [self addSubview:self.colorfulView];
    [self addSubview:self.iconImgView];
    [self bringSubviewToFront:self.iconImgView];
    
}
//设置图标的时候需要使其能够被渲染颜色 方便动画中的变色
- (void)setIconImg:(UIImage *)iconImg {
    UIImage *img = [iconImg imageWithRenderingMode:(UIImageRenderingModeAlwaysTemplate)];
    self.iconImgView.image = img;
    
}
//统一设置主题颜色 使其看起来和谐美观
- (void)setThemeColor:(UIColor *)themeColor {
    self.lineView.backgroundColor = themeColor;
    self.colorfulView.backgroundColor = themeColor;
    [self.iconImgView setTintColor:themeColor];
}
@end

YHCustomMenu.h
#import <UIKit/UIKit.h>
#import "YHCustomMenuView.h"

@interface YHCustomMenu : UIView

//按钮的数量
@property (nonatomic, assign) NSInteger number;
//自定义图标
@property (nonatomic, strong) NSArray *iconImgArr;
//自定义颜色
@property (nonatomic, strong) NSArray *themeColorArr;
//默认选择页
@property (nonatomic, assign) NSInteger defaultIndex;

@end
YHCustomMenu.m
#import "YHCustomMenu.h"
#define SCREEHEIGHT ([UIScreen mainScreen].bounds.size.height - 20)

@interface YHCustomMenu ()
//用于盛放所有自定义菜单视图的数组
@property (nonatomic,retain) NSMutableArray *allViewsArr;
//用于盛放所有颜色的数组
@property (nonatomic,retain) NSMutableArray *allColorArr;
@end
@implementation YHCustomMenu

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
    }
    return self;
}

- (NSMutableArray *)allViewsArr {
    if (!_allViewsArr) {
        self.allViewsArr = [[NSMutableArray alloc] init];
    }
    return _allViewsArr;
}

- (NSMutableArray *)allColorArr {
    if (!_allColorArr) {
        self.allColorArr = [[NSMutableArray alloc] init];
    }
    return _allColorArr;
}
//设置数字之后才能添加 自定义菜单视图
- (void)setNumber:(NSInteger)number {
    CGFloat width = self.frame.size.width;
    CGFloat height = self.frame.size.height;
    for (int i = 0; i < number; i ++) {
        YHCustomMenuView *view = [[YHCustomMenuView alloc] initWithFrame:CGRectMake(0,height/number * i,width,height/number )];
        view.tag = 10000+i;
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
        [view addGestureRecognizer:tap];
        [self addSubview:view];
        [self.allViewsArr addObject:view];
    }
}
//设置图标数组后才能设置 自定义菜单视图的 图标
- (void)setIconImgArr:(NSArray *)iconImgArr {
    for (int i = 0; i < self.allViewsArr.count; i++) {
        YHCustomMenuView *view = self.allViewsArr[i];
        view.iconImg = [UIImage imageNamed:iconImgArr[i]];
    }
}
//设置主题颜色数组后才能设置 自定义菜单视图的 主题颜色
- (void)setThemeColorArr:(NSArray *)themeColorArr {
    [self.allColorArr addObjectsFromArray:themeColorArr];
    for (int i = 0; i < self.allViewsArr.count; i++) {
        YHCustomMenuView *view = self.allViewsArr[i];
        view.themeColor = themeColorArr[i];
    }
}
//设置默认选择的分页 会选中该分页 不选则无
- (void)setDefaultIndex:(NSInteger)defaultIndex {
    YHCustomMenuView *view = self.allViewsArr[defaultIndex - 1];
    [self changeCenterForView:view];
}
//添加点击事件
- (void)tapAction:(UITapGestureRecognizer *)tap {
    YHCustomMenuView *view = (YHCustomMenuView *)[tap view];
    [self changeCenterForView:view];
}

//icon颜色的变化以及彩色遮挡物的位置动画
- (void)changeCenterForView:(YHCustomMenuView *)customView {
    for (YHCustomMenuView *view in self.subviews) {
        NSArray *viewArr = [view subviews];
        if ([view isEqual:customView]) {
            view.userInteractionEnabled = NO;
            for (UIView *view in viewArr) {
                if (view.frame.size.width == self.frame.size.width) {
                    [UIView animateWithDuration:0.3 delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
                        CGPoint center = view.center;
                        center.x += SCREEHEIGHT/7;
                        view.center = center;
                        [customView.iconImgView setTintColor:[UIColor whiteColor]];
                    } completion: nil];
                }
            }
        } else {
            view.userInteractionEnabled = YES;
            for (UIView * subview in viewArr) {
                if (subview.frame.size.width == self.frame.size.width) {
                    if (subview.frame.origin.x >= 0) {
                        [UIView animateWithDuration:0.3 delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{
                            CGPoint center = subview.center;
                            center.x -= SCREEHEIGHT/7;
                            subview.center = center;
                            [view.iconImgView setTintColor:self.allColorArr[(view.tag - 10000)]];
                        } completion: nil];
                    }
                }
            }
        }
    }
}
@end

使用示例:


到此结束。
有些细节我可能没有处理好,代码质量也不高。
所以希望大家能够指出我的问题和错误,共同学习,共同进步。

github地址在上面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值