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地址在上面