Objective-C 混用UITabBar与UINavigation

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、pandas是什么?
  • 二、使用步骤
    • 1.引入库
    • 2.读入数据
  • 总结


前言

混用UITabBar与UINavigation做app,tab和nav,有时候显示有时候需要隐藏,记录目前使用的解决方案。


一、效果

1、主页使用UITabBar管理,有三个tab分页

2、在tab分页的根视图时显示tab,隐藏nav。

3、二级页面全部用UINavigationController管理。

4、使用pushViewController打开页面时,隐藏tab,显示nav;

5、导航栏的文字显示黑色

6、导航栏的返回按钮不显示中文

 

二、实现

1.AppDelegate.m

代码如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    self.window.rootViewController = [[MainTabBarController alloc] init];
    
    // 设置导航栏的文字为黑色
    // 满足5【导航栏的文字显示黑色】
    [[UINavigationBar appearance] setTintColor: [UIColor blackColor]];

    return YES;
}

// 其他代码.....

在AppDelegate.m中,设置rootViewController为【MainTabBarController】

2.MainTabBarController.m

代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createBottomMenuIconButton];
    // 其他代码....
}

-(void)createBottomMenuIconButton{
    NSMutableArray *bottomViewCtrls  = [NSMutableArray arrayWithCapacity:0];

    NSArray* bottomMenus = [self getLocalBottomMenu];
    for (NSDictionary *bottomMenu in bottomMenus) {
        NSString *name =  [bottomMenu objectForKey: @"name"];
        NSString *normal =  [bottomMenu objectForKey: @"normal"];
        NSString *highlighted =  [bottomMenu objectForKey: @"highlighted"];

        //结合 xx.class 对象,动态创建UIViewController
        UIViewController *vc = [[[bottomMenu objectForKey: @"vcclass"] alloc] init];
        // 满足3【二级页面全部用UINavigationController管理】
        UINavigationController *nav = [self createBottomMenu:vc menuName:name normal: normal highlighted: highlighted];
        [self.bottomViewCtrls addObject:nav];
    }
    
    //有底部导航菜单
    // 满足1【使用UITabBar管理,有三个tab分页】
    if(bottomViewCtrls.count > 0){
        self.viewControllers= bottomViewCtrls;
    }
}

- (UINavigationController*) createBottomMenu: (UIViewController*) vc
                                    menuName: (NSString*) menuName
                                      normal: (NSString*) normal
                                 highlighted: (NSString*) highlighted{
    vc.tabBarItem.title = menuName;

    UIImage* imageNormal = [UIImage imageNamed: normal];
    vc.tabBarItem.image = imageNormal;
    UIImage* imagePressed = [UIImage imageNamed: highlighted];
    vc.tabBarItem.selectedImage = [imagePressed imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

    //将分页设置成UINavigationController的根视图。
    //这样包装之后,才能正常使用pushViewController打开页面
    UINavigationController* nav = [[UINavigationController alloc]initWithRootViewController:vc];
    return nav;
}

-(NSArray *)getLocalBottomMenu{
    NSArray *bottomMenus = @[
        @{@"id":@"home",@"name":@"首页",@"normal":@"tab_home",@"highlighted":@"tab_home_active",@"vcclass":TabItemHome.class},
        @{@"id":@"message",@"name":@"消息",@"normal":@"tab_message",@"highlighted":@"tab_message_active",@"vcclass":TabItemMessage.class},
        @{@"id":@"profile",@"name":@"我的",@"normal":@"tab_profile",@"highlighted":@"tab_profile_active",@"vcclass":TabItemProfile.class}
    ];
    return bottomMenus;
}

(1)通过【self.viewControllers= bottomViewCtrls】设置tab的分页。

(2)如果创建tab分页的时候,不用UINavigationController包装一下,在页面中使用pushViewController,就会报错,提示当前视图不支持UINavigationController。

(3)结合xx.class和[[[bottomMenu objectForKey: @"vcclass"] alloc] init],动态创建UIViewController。

(4)tab分页需要增删改时,修改【getLocalBottomMenu】的代码,即可。

2.tab分页的基类BaseTabViewController

代码如下:

//BaseTabViewController.h
-(void) setTitle:(nonnull NSString*) title;
-(void)openPage:(UIViewController*)page;



//BaseTabViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    // 满足6【导航栏的返回按钮不显示中文】
    [self setNavSetting];
    // 其他代码...
}

// 满足2【在tab分页的根视图时显示tab,隐藏nav】
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // 隐藏导航
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    // 其他代码...
}

// 满足4【使用pushViewController打开页面时,隐藏tab,显示nav】
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    // 显示导航
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    // 其他代码...
}

-(void) setTitle:(nonnull NSString*) title{
    self.navigationItem.title = title;
}
-(void)setNavSetting {
    // 设置导航栏的返回按钮没有中文,对下一个打开的页面起效
    UIBarButtonItem* backBtn = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationItem.backBarButtonItem = backBtn;
    
}

-(void)openPage:(UIViewController*)page {
    // 隐藏下面的tab
    page.hidesBottomBarWhenPushed = YES;

    //通过nav打开页面
    [self.navigationController pushViewController:page animated:YES];
    
}

(1)通过【page.hidesBottomBarWhenPushed = YES】隐藏tabbar;

(2)导航栏的返回按钮,总是要父页设置的。所以,在当前页,需要设置返回按钮,去掉它自带的文字;

(3)【viewWillAppear】当页面要展示的时候,隐藏导航;【viewWillDisappear】当页面要隐藏时,显示导航。

3.HomeTab.m

代码如下:

//HomeTab.h
@interface HomeTab : BaseTabViewController
// 其他代码.....


//HomeTab.m

// 在要打开页面的方法中,调用openPage打开PageA页面
[self openPage: [[PageA alloc] init]];

在h文件中,将HomeTab类设置成继承BaseTabViewController,所以在要打开页面的方法中,可以直接调用openPage打开PageA页面。

以上,就是tab相关的设置

4.二级页面的基类BasePageViewController

代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // 满足6【导航栏的返回按钮不显示中文】
    [self setNavSetting];
    // 其他代码...
}

-(void)setNavSetting {
    // 设置导航栏的返回按钮没有中文,对下一个打开的页面起效
    UIBarButtonItem* backBtn = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationItem.backBarButtonItem = backBtn;
    
}

-(void) setTitle:(nonnull NSString*) title {
    self.navigationItem.title = title;
}

将复用的内容,做到基类中。

5.二级页面pageA

代码如下:

//PageA.h
@interface PageA : BasePageViewController


//PageA.m

//调用pushViewController打开页面
[self.navigationController pushViewController:page animated:YES];

在h文件中,将PageA类设置成继承BasePageViewController。


总结

以上是我目前使用的一种UITabBar与UINavigation混用方案,基本满足了我的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/32488.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

03 Web全栈 浏览器内置对象/事件/ajax

浏览器是一个JS的运行时环境,它基于JS解析器的同时,增加了许多环境相关的内容,用一张图表示各个运行环境和JS解析器的关系如下: 我们把常见的,能够用JS这门语言控制的内容称为一个JS的运行环境,常见的运行环…

专业科普:什么是单片机?

一、什么是单片机 单片机诞生于20世纪70年代末,它是指一个集成在一块芯片上的完整计算机系统。单片机具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统,目前大部分还会具有外存。同时集成诸如通讯接口、定时器&#xff…

Edge浏览器可以多开吗?

问答链接:Edge浏览器可以多开吗? 可以。 如果你的edge浏览器是默认路径安装的,那么打开命令提示符窗口输入以下两条命令即可启动一个数据完全隔离的edge浏览器。 mkdir C:\logs001 "C:\Program Files (x86)\Microsoft\Edge\Applicati…

【宝塔服务器】宝塔通过composer安装TP依赖

屡屡碰壁,安装一个项目,发现没有依赖,需要使用composer安装,没接触过,找了网上也没攻略,自己弄了后有以下问题,经过调整解决了: 报错1:没有安装fileinfo扩展 Loading composer rep…

Linux下RPM软件包管理

目录 1、软件包管理介绍1.1、软件包分类1.2、源码包1.3、RPM包 2、RPM包管理-包命名和依赖性2.1、RPM命名规则2.2、RPM包依赖性 3、RPM包管理-安装升级和与卸载3.1、包全名与包名3.2、RPM安装3.3、RPM包升级3.4、卸载 4、RPM包管理-查询4.1、查询是否安装4.2、查询软件包详细信…

Java集合相关问题

java集合框架体系 数据结构 算法复杂度分析 时间复杂度分析:对代码运行时间所消耗时间多少进行分析空间复杂度分析:对代码运行所占用的内存的大小进行分析 时间复杂度 时间复杂度分析:来评估代码的执行耗时 假如执行每行代码的执行耗时一…

阿里云服务器ping不通如何解决?

阿里云服务器ping不通?什么原因?在安全组中允许【全部 ICMP(IPv4)】,当然阿里云服务器禁ping也是通过配置安全组的ICMP规则来实现的,阿里云服务器网来详细说下安全组开通ping功能教程: 目录 阿里云服务器ping不通的解…

微服务: sleuth和zipkin的用处与zipkin安装使用(下)

目录 0. 上篇传送门: 1. 前言简介 mq安装传送门: 微服务: 01-rabbitmq的应用场景及安装(docker) 1.1 Sleuth是一款分布式跟踪解决方案。 1.2 Zipkin是一个开源的分布式跟踪系统。 2. zipkin安装方式 2.1 windows下安装zipkin: 2.1.0 下载jar包位置 2.1.1 下载后,找…

华为防火墙之NAT技术

1.源NAT 源NAT技术对IP报文的源地址进行转换,将私网IP地址转换成公网IP地址,使大量私网用户可以利用少量公网IP地址访问Internet,大大减少了对公网IP地址的消耗。 源NAT转换的过程如下图所示,当私网用户访问Internet的报文到达防…

银河麒麟系统安装mysql数据库[mysql-5.7.28-linux-glibc2.12-x86_64]

银河麒麟系统安装mysql数据库 1.1 准备材料 mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz MySQL5.7下载地址 https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz 1.1 安装前准备工作 1、检查是否已经安装MySQL [rootlocalhost ~]# rpm …

redismariadb + keepalived 高可用

目录 机器准备 安装后服务 redis 安装redis mariadb 安装mariadb 启动和配置 互为主从同步配置 keepalived keepalived安装 修改主从 keepalived的配置 主从配置-mariadb监控 主从配置-redis监控 查看和使用 Keepalived Mariadb redis 机器准备 两台机器&…

transformer零基础学习

声明:以下文章链接仅用于个人学习与备忘。 基础知识 1:零基础解析教程 [推荐] https://zhuanlan.zhihu.com/p/609271490 2:Transformer 详解 [推荐] https://wmathor.com/index.php/archives/1438/ 3:如何从浅入深理解transfor…

行为型模式--状态模式

目录 举例 状态模式 定义 结构 代码实现 优缺点 优点: 缺点: 使用场景 举例 【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一 种状态改变,都…

STM32外设系列—BH1750

文章目录 一、BH1750简介二、BH1750原理图三、BH1750数据手册3.1 指令集3.2 IIC通信读/写 四、BH1750程序设计4.1 IIC程序4.2 BH1750初始化程序4.3 读取BH1750测量结果4.4 获取光照强度4.5 相关宏定义 五、应用实例六、拓展应用6.1 实时调节LED亮度6.2 实时调整颜色阈值 一、BH…

C++【位图/布隆过滤器—海量数据处理】

文章目录 一、位图(1)位图概念介绍(2)简单模拟实现(3)位图应用 二、布隆过滤器(1)关于布隆过滤器概念及介绍(2)布隆过滤器的使用场景(3&#xff0…

【前端布局篇】浮动、定位、弹性布局,固比固、双飞翼、圣杯布局

一、布局方式介绍 布局模型是基于盒模型基础上进行的拓展,关于布局有流式布局(标准的布局),浮动布局、定位布局、flex布局等。 1.1 标准流(流动模型) 描述:元素按照自己默认的元素类型在页面…

Unity3D 连接MySQL数据库

1、MySQL下载安装运行 详见:MySQL下载安装运行 2、使用mysql-connector-net (1)官方下载地址:https://downloads.mysql.com/archives/c-net/,下载后直接双击安装即可。 提示:不要使用版本过高的connect…

Jmeter(三) - 从入门到精通 - 测试计划(Test Plan)的元件(详解教程)

1.简介 上一篇中我已经教你如何通过JMeter来创建一个测试计划(Test Plan),那么这一篇我们就将JMeter启动起来,创建一个测试计划(Test plan),然后现在给大家介绍一下测试计划(Test P…

C# wpf 附加属性实现任意控件拖动调整大小

摘自这里 https://blog.csdn.net/u013113678/article/details/121719278 调试效果如下 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using Syst…

【信号】信号处理与进程通信:快速上手

目录 0. 信号概述 1. 产生信号的方式: 1.1 当用户按某些终端键时,将产生信号。 1.2 硬件异常将产生信号。 1.3 软件异常将产生信号。 1.4 调用kill函数将发送信号。 1.5 运行kill命令将发送信号。 2. 信号的默认(缺省)处理…
最新文章