iOS仿小猪导航栏效果
2017-11-07 本文已影响112人
刘太哥
上一个公司的技术总监 看我不顺眼,把我开除啦。所以我来写一篇文章记录一下项目里用到的一个动画,分享给大家。
哈哈,开玩笑。本人新手,分享出来一些思路供大家讨论,如果有更好的解决办法,别忘了告诉我哦,一起进步嘛。
话不多说直接奔主题,上一个项目的UI设计师 设计出来一个动画效果,做完以后,才知道是仿的小猪短租。大家先看看效果图 租房详情交互.gif当看到这个效果图的时候,想到的肯定是自定义导航栏,因为当时项目比较赶,而且在第一版原型出来的时候还没有这个效果图,所以,当时的项目也没有自定义导航栏,都是用的原生的。
那我们该怎么办呢?
首先,肯定是要把原生的导航栏去掉,然后做一个假的出来。
去掉导航栏的办法:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController.navigationBar setHidden:YES];
}
- (void)viewWillDisappear:(BOOL)animated{
[self.navigationController.navigationBar setHidden:NO];
}
这样,当前页面的navigationBar 就隐藏了。
然后自己写三个按钮,返回,分享和收藏加在当前self.view
//导航栏
- (void)configNavigationBar{
WS(ws);
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[backBtn setImage:[UIImage imageNamed:@"ad_back_white"] forState:UIControlStateNormal];
[backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
_shareBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_shareBtn setImage:[UIImage imageNamed:@"ad_share_white"] forState:UIControlStateNormal];
[_shareBtn setImage:[UIImage imageNamed:@"ad_share_red"] forState:UIControlStateSelected];
[_shareBtn addTarget:self action:@selector(shareBtnAction) forControlEvents:UIControlEventTouchUpInside];
_collectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_collectBtn addTarget:self action:@selector(collectButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_collectBtn setImage:[UIImage imageNamed:@"ad_collection_white"] forState:UIControlStateNormal];
[_collectBtn setImage:[UIImage imageNamed:@"ad_collection_red"] forState:UIControlStateSelected];
[self.view addSubview:backBtn];
[self.view addSubview:_shareBtn];
[self.view addSubview:_collectBtn];
[backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.view).offset(10);
make.top.equalTo(ws.view).offset(35);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
[_shareBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(backBtn);
make.right.equalTo(ws.view).offset(-73);
make.size.mas_offset(CGSizeMake(22, 22));
}];
[_collectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(backBtn);
make.right.equalTo(ws.view).offset(-30);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
}
image.png
看起来就是这个样子。
接下来就是自定义view,我在这里就叫navigationView了。
其实事情大概是这样子的
image.png
navigationView已经在这上面了,只不过它的alpha = 0.0 而已,还有就是navigationView上的button都是在屏幕的最右侧,只有分享和收藏两个按钮是和当前View上的重合。
剩下的就超级简单了,滑动tableVIew超过广告图的时候把navigationView慢慢显示出来,当它的alpha = 1.0 也就是说完全显示出来后,让里面的按钮位置发生变化就可以喽。
是不是我这思路很简单?不知道文字说了这么半天,大家有没有听懂。
还是直接上代码吧。
navigationView.h
#import <UIKit/UIKit.h>
@protocol NavigationViewDelegate <NSObject>
- (void)NavigationViewWithScrollerButton:(UIButton *)btn;
- (void)NavigationViewGoBack;
- (void)NavigationViewGoShare;
- (void)NavigationViewGoCollect;
@end
@interface NavigationView : UIView
@property (nonatomic, strong) UIButton *collectBtn;
@property (nonatomic, weak) id<NavigationViewDelegate> naviDelegate;
@property (nonatomic, strong) UIButton *backBtn;
//向左移动
- (void)navigationAnimation;
//恢复原位
- (void)resetFrame;
//选中恢复
- (void)resetBtns;
@end
navigationView.m
#import "NavigationView.h"
static const CGFloat width = 23; //宽度
static const CGFloat space = 15; //间距
@interface NavigationView ()
@property (nonatomic, strong) UIButton *shareBtn;
@property (nonatomic, strong) UIView *parting;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) NSArray *titleArr;
@property (nonatomic, assign) BOOL animatFinsh;
@end
@implementation NavigationView
- (instancetype)init{
self = [super init];
if (self) {
self.titleArr = @[@"图片",@"概况",@"信息",@"设施",@"租含",@"安保",@"出行",@"宠物",@"位置",@"退订",@"评价",@"养学",@"周边"];
[self setupUI];
}
return self;
}
- (void)setupUI{
WS(ws);
self.backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.backBtn setImage:[UIImage imageNamed:@"ad_back_black"] forState:UIControlStateNormal];
[self.backBtn addTarget:self action:@selector(backViewController) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.backBtn];
[self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws).offset(10);
make.top.mas_equalTo(@35);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
self.shareBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.shareBtn setImage:[UIImage imageNamed:@"ad_share_black"] forState:UIControlStateNormal];
self.shareBtn.userInteractionEnabled = NO;
[self.shareBtn addTarget:self action:@selector(shareHouse) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.shareBtn];
[self.shareBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(ws.backBtn);
make.right.equalTo(ws).offset(-73);
make.size.mas_offset(CGSizeMake(22, 22));
}];
self.collectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.collectBtn setImage:[UIImage imageNamed:@"ad_collection_black"] forState:UIControlStateNormal];
[self.collectBtn setImage:[UIImage imageNamed:@"ad_collection_red"] forState:UIControlStateSelected];
[self.collectBtn addTarget:self action:@selector(collecHouse) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.collectBtn];
[self.collectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(ws.backBtn);
make.right.equalTo(ws).offset(-30);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
self.parting = [[UIView alloc]init];
self.parting.backgroundColor = APP_BLUECOLOR;
[self addSubview:self.parting];
[self.parting mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.mas_right);
make.centerY.equalTo(ws.backBtn);
make.width.mas_equalTo(0.5);
make.height.mas_equalTo(14);
}];
UIView *line = [[UIView alloc]init];
line.backgroundColor = APP_LINECOLOR;
[self addSubview:line];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws);
make.right.equalTo(ws);
make.bottom.equalTo(ws);
make.height.mas_equalTo(@0.5);
}];
self.scrollView = [[UIScrollView alloc]init];
self.scrollView.showsHorizontalScrollIndicator = NO;
[self addSubview:self.scrollView];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.mas_right);
make.bottom.equalTo(ws);
make.size.mas_equalTo(CGSizeMake(100, 44));
}];
for (int i = 0; i < self.titleArr.count; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:self.titleArr[i] forState:UIControlStateNormal];
[btn setTitleColor:APP_BLACKCOLOR forState:UIControlStateNormal];
[btn setTitleColor:APP_BLUECOLOR forState:UIControlStateSelected];
[btn addTarget:self action:@selector(touchBtn:) forControlEvents:UIControlEventTouchUpInside];
btn.tag = 10000+i;
btn.titleLabel.font = F11;
[self.scrollView addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.scrollView).offset(space + (width + space) * i);
make.centerY.equalTo(ws.scrollView).offset(4);
make.height.mas_equalTo(10);
make.width.mas_equalTo(width);
}];
}
self.scrollView.contentSize = CGSizeMake(space + (width + space) * self.titleArr.count, 44);
}
- (void)resetBtns
{
for (UIView *btn in self.scrollView.subviews) {
if ([btn isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton*)btn;
[button setTitleColor:APP_BLACKCOLOR forState:UIControlStateNormal];
}
}
}
- (void)navigationAnimation{
WS(ws);
if (_animatFinsh == NO) {
for (int i = 0; i<4; i++) {
switch (i) {
case 0:{
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionTransitionNone animations:^{
[ws.shareBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(ws.backBtn);
make.left.equalTo(ws).offset(39);
make.size.mas_offset(CGSizeMake(22, 22));
}];
[self layoutIfNeeded];
} completion:nil];
break;
}
case 1:{
[UIView animateWithDuration:0.5 delay:0.1 options:UIViewAnimationOptionTransitionNone animations:^{
[ws.collectBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(ws.backBtn);
make.left.equalTo(self.shareBtn.mas_right).offset(25);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
[self layoutIfNeeded];
} completion:nil];
break;
}
case 2:{
[UIView animateWithDuration:0.5 delay:0.2 options:UIViewAnimationOptionTransitionNone animations:^{
[ws.parting mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.collectBtn.mas_right).offset(25);
make.centerY.equalTo(ws.backBtn);
make.width.mas_equalTo(0.5);
make.height.mas_equalTo(14);
}];
[self layoutIfNeeded];
} completion:nil];
break;
}
case 3:{
[UIView animateWithDuration:0.5 delay:0.3 options:UIViewAnimationOptionTransitionNone animations:^{
[ws.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.parting.mas_right);
make.bottom.equalTo(ws);
make.right.equalTo(ws);
make.height.mas_equalTo(44);
}];
[ws layoutIfNeeded];
} completion:^(BOOL finished) {
_animatFinsh = YES;
}];
break;
}
default:
break;
}
}
}
}
- (void)resetFrame{
WS(ws);
if (_animatFinsh == YES) {
for (int i = 0; i<4; i++) {
switch (i) {
case 0:{
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{
[ws.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.mas_right);
make.bottom.equalTo(ws);
make.size.mas_equalTo(CGSizeMake(100, 44));
}];
[ws layoutIfNeeded];
} completion:nil];
break;
}
case 1:{
[UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionTransitionNone animations:^{
[ws.parting mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(ws.mas_right);
make.centerY.equalTo(ws.backBtn);
make.width.mas_equalTo(0.5);
make.height.mas_equalTo(14);
}];
[self layoutIfNeeded];
} completion:^(BOOL finished) {
}];
break;
}
case 2:{
[UIView animateWithDuration:0.3 delay:0.2 options:UIViewAnimationOptionTransitionNone animations:^{
[self.collectBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(ws.backBtn);
make.right.equalTo(ws).offset(-30);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
[self layoutIfNeeded];
} completion:nil];
break;
}
case 3:{
[UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionTransitionNone animations:^{
[self.shareBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(ws.backBtn);
make.right.equalTo(ws).offset(-73);
make.size.mas_offset(CGSizeMake(22, 22));
}];
[self layoutIfNeeded];
} completion:^(BOOL finished) {
_animatFinsh = NO;
}];
break;
}
default:
break;
}
}
}
}
- (void)touchBtn:(UIButton *)btn{
DebugLog(@"yyyyyyyyyyyyyyyyyyyyyyyy");
if ([_naviDelegate respondsToSelector:@selector(NavigationViewWithScrollerButton:)]) {
[_naviDelegate NavigationViewWithScrollerButton:btn];
}
}
- (void)backViewController{
if ([self.naviDelegate respondsToSelector:@selector(NavigationViewGoBack)]) {
[self.naviDelegate NavigationViewGoBack];
}
}
- (void)shareHouse{
if ([self.naviDelegate respondsToSelector:@selector(NavigationViewGoShare)]) {
[self.naviDelegate NavigationViewGoShare];
}
}
- (void)collecHouse{
if ([self.naviDelegate respondsToSelector:@selector(NavigationViewGoCollect)]) {
[self.naviDelegate NavigationViewGoCollect];
}
}
@end
最后在controller 里进行移动就好了
#pragma mark - ScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 计算当前偏移位置
CGFloat threholdHeight = (SCREEN_WIDTH * 9 / 16) - 64;
if (scrollView.contentOffset.y >= 0 &&
scrollView.contentOffset.y <= threholdHeight) {
self.alpha = scrollView.contentOffset.y / threholdHeight;
self.navigationView.alpha = self.alpha;
}
else if (scrollView.contentOffset.y < 0){
scrollView.contentOffset = CGPointMake(0, 0);
}
else{
self.navigationView.alpha = 1.0;
self.shareBtn.alpha = 0.0f;
self.collectBtn.alpha = 0.0f;
}
if (self.alpha == 0) {
self.shareBtn.alpha = 1.0;
self.collectBtn.alpha = 1.0;
}
if (scrollView.contentOffset.y > threholdHeight &&
self.navigationView.alpha == 1.0) {
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
[self.navigationView navigationAnimation];
self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
}else{
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
[self.navigationView resetFrame];
}
}
不知道大家听明白没有,因为代码是直接写在项目里的。如果大家需要的话,我可以抽出来,放在GitHub上。如果谁有更好,更完美的解决办法,可以分享出来。谢谢
简单的把demo弄了一下
https://github.com/liuhe62/NaviAnimation.git