11导航栏变44 ios

2016-06-07 15:32:01 CodingFire 阅读数 3525

最近博主对渐变导航栏进行了改进,原来的是只有在头部部分400以内会改变,现在当在中部上下滚动时也会有类似的功能,和百度贴吧的功能类似,需要的请查看博客链接:http://blog.csdn.net/CodingFire/article/details/53705318


看到有人说渐变的导航栏,所以就随便来写写,根据渐变原理,应该是控件在滚动的时候,根据偏移量来设置导航栏背景的透明度。
这就简单了,废话不多说,直接上代码:

 //
//  ViewController.m
//  NavClear
//
//  Created by 刘浩浩 on 16/6/7.
//  Copyright © 2016年 CodingFire. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()<UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource>
{
    UIImageView *barImageView;
    UITableView *myTableView;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor=[UIColor whiteColor];


    self.navigationController.navigationBar.barTintColor=[UIColor orangeColor];

    self.title=@"This is my title!";
    self.navigationController.navigationBar.tintColor = [UIColor blackColor];

    myTableView=[[UITableView alloc]initWithFrame:self.view.bounds];
    myTableView.delegate=self;
    myTableView.dataSource=self;
    [self.view addSubview:myTableView];
    UIImageView *imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 270)];
    imageView.image=[UIImage imageNamed:@"1.png"];
    myTableView.tableHeaderView=imageView;

    barImageView = self.navigationController.navigationBar.subviews.firstObject;

}
#pragma mark - UITableViewDelaget
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 40;
}
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    cell.textLabel.text=[NSString stringWithFormat:@"%ld",indexPath.row];
    return cell;
}


-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    self.navigationController.navigationBar.alpha=1-scrollView.contentOffset.y/400;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

这里透明度变化的维度自己控制,我这边在400以内变化,超出的透明度都为1,看到别人写的隐藏导航条的方法,这里拿出来分享一下:

//这里的图片是导航条的背景图片,相当于设置了nil
[self.navigationController.navigationBar setBackgroundImage:[UIImage new]                                       forBarMetrics:UIBarMetricsDefault];  
//这里的图片是下面那条线,如果不设置会看到64像素位置的那条黑线
self.navigationController.navigationBar.shadowImage = [UIImage new];
//还有一种最简单的方法
    [self.navigationController setNavigationBarHidden:YES animated:YES];

第二个知识点,拿到导航栏背景图,其实导航栏背景图是导航栏的第一个子集,所以拿到所有的导航栏子集,取第一位:

    barImageView = self.navigationController.navigationBar.subviews.firstObject;

这里要注意,不能写成

    self.navigationController.navigationBar.alpha=1-scrollView.contentOffset.y/400;

否则nav上的标题按钮也会消失,而实用:

    barImageView = self.navigationController.navigationBar.subviews.firstObject;

隐藏的只是背景图片,并不会把nav上面的其他子集隐藏。附上下载地址:https://github.com/codeliu6572/NavClear

2017-08-23 17:55:27 Iven_ma 阅读数 5712

最近做项目实现新的需求,初始状态导航栏透明,随着滑动的过程中,改变导航栏的透明度,逐渐颜色加深。

网上找到了两种解决方案。

第一种,通过研究导航栏的结构图,找出影响背景颜色的控件,对其进行控制改变。

NavigationBar背后有一张类型_UINavigationBarBackground(UIImageView的子类)的视图,所以我们设置背景的时候就是设置的_UINavigationBarBackground的image。然后通过改变这个控件的透明度来实现。

该方法是网上的一个大神,实现的比较好,感兴趣的小伙伴可以参考一下,文章链接
http://www.cocoachina.com/ios/20160606/16608.html
不过,我在使用大神封装的类库,最终并没有解决问题,实现不了我想要的功能,所以继续在网上探索其它方法。

第二种,实现了我想要的效果,在这里推荐大家优先尝试下面的解决方案。

在导航栏上加一个view,自己控制view的背景颜色,初始的时候不需要设置背景颜色,然后在滑动过程中,通过滑动的数据改变透明度,直接上代码。

//懒加载实现背景View
- (UIView*)bgView {
    if (_bgView == nil) {
        _bgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height + 20)];
        [self.navigationController.view insertSubview:_bgView belowSubview:self.navigationController.navigationBar];

    }
    return _bgView;
}

然后在代理方法中,改变alpha的值。这里由于主页页面较长通过滑动600的距离后达到透明度的值改为1。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat alpha = scrollView.contentOffset.y/600;
    if (alpha > 1) {
        alpha = 1;
    }
    if (scrollView == _backgroundScrollV) {  
        [self bgView].backgroundColor = [UIColor colorWithRed:242.0/255 green:100.0/255 blue:50.0/255 alpha:alpha];
    }
}

初始页面

这里写图片描述

这里写图片描述

2018-10-16 14:48:30 u010960265 阅读数 3547

首先我们来看下效果:
在这里插入图片描述

下面有几种方案:

1.设置渐变图片

根据上面设置为透明的方法,我们最直接能想到的还是setBackgroundImage,根据滑动距离去设置图片的alpha。是的,我们是去设置图片,而不是设置UIView,这样的话就需要你不停的去生成新图片赋给BackgroundImage,这样感觉是不是会不太好?

2.运行时动态绑定

我们可以在运行时动态绑定他的背景视图,然后设置他的背景透明度,网上有一个通过类别方式动态绑定实现导航栏颜色渐变的三方框架,感兴趣的朋友可以自行去研究研究LTNavigation。

3.直接获取那张ImageView,然后设置他的透明度。

其实我们从结构图中可以看出来,它是NavigationBar的子视图,我们可以通过for…in循环遍历navigationBar.subviews,然后获得这个view。

当然,更简单的,它其实就在subviews的第一个,即我们可以这样:

barImageView = self.navigationController.navigationBar.subviews.firstObject;

我们可以用一个全局的imageView引用他,以免我们每次都要写一长串。

最后,我们仅仅只需要在scrollViewDidScroll里面,根据偏移量来动态改变barImageView的背景颜色(或者透明度)就行了。

例如我们需要在-64(默认的最小偏移量)到200之间变化:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat minAlphaOffset = - 64;
    CGFloat maxAlphaOffset = 200;
    CGFloat offset = scrollView.contentOffset.y;
    CGFloat alpha = (offset - minAlphaOffset) / (maxAlphaOffset - minAlphaOffset);
    _barImageView.alpha = alpha;
}

就这样你就可以实现我在文章一开始那个图片的效果了(其实并不是,tintColor和satusBarStyle还没变)。

Tips

1)你也可以动态的更改的状态栏和标题的颜色以和导航栏更匹配

//状态栏
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
//标题颜色
self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor someColor]}
//导航栏子控件颜色
self.navigationController.navigationBar.tintColor = [UIColor someColor];

2)注意释放tableView 的 delegate(不然你进进出出时候会发现哪里好像不太对)

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.tableView.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.tableView.delegate = nil;
}

3)导航栏是公有的

所以你可能需要在ViewWillDisappear里面再把导航栏设置为你需要的样子
我自己封装了一些导航栏变化效果,使用简单,欢迎大家尝试:HQShopDemo

2018-11-12 14:16:46 a18339063397 阅读数 1855

//给导航条设置一个空的背景图 使其透明化

[self.navigationController.navigationBar setBackgroundImage:[UIImagenew] forBarMetrics:UIBarMetricsDefault];

//去除导航条透明后导航条下的黑线

[self.navigationController.navigationBar setShadowImage:[UIImagenew]];

根据UITableView 的scrollViewDidScroll方法,我们能实时获得contentOffset.y值,根据该值的变化对刚才扩展的UINavigationBar的背景色的alpha值,做相应的变化,具体实现:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat reOffset = scrollView.contentOffset.y + (kScreenH - 64) * 0.2; 
    CGFloat alpha = reOffset / ((kScreenH - 64) * 0.2);
    if (alpha <= 1)//下拉永不显示导航栏
    {
        alpha = 0;
    }
    else//上划前一个导航栏的长度是渐变的
    {
        alpha -= 1;
    }
    // 设置导航条的背景图片 其透明度随  alpha 值 而改变
    UIImage *image = [self imageWithColor:[UIColor colorWithRed:0.227 green:0.753 blue:0.757 alpha:alpha]];
    [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
/// 使用颜色填充图片
- (UIImage *)imageWithColor:(UIColor *)color
{
    // 描述矩形
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    // 开启位图上下文
    UIGraphicsBeginImageContext(rect.size);
    // 获取位图上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    // 使用color演示填充上下文
    CGContextSetFillColorWithColor(context, [color CGColor]);
    // 渲染上下文
    CGContextFillRect(context, rect);
    // 从上下文中获取图片
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    // 结束上下文
    UIGraphicsEndImageContext();
    return theImage;
}

2017-10-19 12:01:45 iOS_PING 阅读数 5931

部分总结;


(一)导航栏高度的变化

(1) iOS11之前导航栏默认高度为44pt(这里高度指NavigationBar);

(2) iOS11之后如果设置了大标题样式, 则为96pt,默认情况下还是44pt;

(3) 但在iPhoneXstatusBar20pt变成了44pt,所以iPhoneX上高度(statusBar + NavigationBar)变为88pt,如果项目里隐藏了导航栏加了自定义按钮之类的,这里需要注意适配一下。


if (@available(iOS 11.0, *)) {

            //iOS11之后

            

            //导航大标题, 上滑到顶部时动态切换大小标题样式 (导航栏高度UINavigationBar = 44/96)

            self.navigationController.navigationBar.prefersLargeTitles = YES;

            //自动模式,依赖于上一个item的设置; 上一个item设置为自动并且当前导航栏prefersLargeTitles=YES,则显示大标题样式;

            self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;

//            //prefersLargeTitles=YES,滚动到顶部时,当前总是显示大标题样式

//            self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAlways;

//            //prefersLargeTitles=YES,滚动到顶部时,当前也总不会显示大标题样式

//            self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;

            

            //标题样式变化时, btnframe不变

            UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"设置" style:UIBarButtonItemStylePlain target:self action:@selector(testDidClick)];

            self.navigationItem.rightBarButtonItem = item;

            

            //标题样式变化时, btnframe不变

            UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(testDidClick)];

            self.navigationItem.leftBarButtonItem = item1;

            

            //titleView

            

        } else {

            // Fallback on earlier versions

            

            //titleView


            

        }



(二) 导航栏图层及对titleView布局的影响

iOS11之后titleView层级发生了变化, 具体如图展示: