iOS开发-自定义TabBar&TabBarButton实现自动切换

Flutter之TabBar篇 使用方法: 第二种采用的三方插件 第三种自定义 阅读详情

 

//

//  ZZTabBarButton.h

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015年 ZZ_Macpro. All rights reserved.

//

 

#import <UIKit/UIKit.h>

 

@interface ZZTabBarButton :UIButton

/**

 *  tabbar 上面的子控件只能是UITabBarItem

 */

@property (nonatomic,weak) UITabBarItem *item;

@end

 

 

 

 

//

//  ZZTabBarButton.m

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015年 ZZ_Macpro. All rights reserved.

//

 

// 图标的比例

#define ZZTabBarButtonImageRatio 0.65

 

#import "ZZTabBarButton.h"

#import "ZZBadgeButton.h"

 

constdouble ZZTabBarImageRatio = 0.65;

 

#define ZZTabBarButtonTitleColor (iOS7 ? [UIColor blackColor] : [UIColor whiteColor])

#define ZZTabBarButtonTitleSelectedColor (iOS7 ? ZZColor(236,103, 0) : ZZColor(253,163, 25))

 

@interface ZZTabBarButton()

@property (weak, nonatomic) ZZBadgeButton *badgeButton;

@end

 

@implementation ZZTabBarButton

 

- (id)initWithFrame:(CGRect)frame

{

   self = [superinitWithFrame:frame];

   if (self) {

        // 1.图片居中

        self.imageView.contentMode =UIViewContentModeCenter;

        

        // 2.文字居中

        self.titleLabel.textAlignment =NSTextAlignmentCenter;

        self.titleLabel.font = [UIFontsystemFontOfSize:11];

        [selfsetTitleColor:ZZTabBarButtonTitleSelectedColorforState:UIControlStateSelected];

        [selfsetTitleColor:ZZTabBarButtonTitleColorforState:UIControlStateNormal];

        

        // 3.设置选中时的背景图片

       if (!iOS7) {

            [selfsetBackgroundImage:[UIImageresizedImageWithName:@"tabbar_slider"]forState:UIControlStateSelected];

        }

        

        // 4.添加一个显示红色提醒数字的按钮

        [selfsetupBadgeButton];

    }

    return self;

}

 

- (void)setupBadgeButton

{

   ZZBadgeButton *badgeButton = [[ZZBadgeButtonalloc] init];

    badgeButton.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;

    [selfaddSubview:badgeButton];

   self.badgeButton = badgeButton;

}

 

/**

 *  目的是去掉父类在高亮时所做的操作

 */

- (void)setHighlighted:(BOOL)highlighted {}

 

#pragma mark - 覆盖父类的2个方法

#pragma mark 设置按钮标题的frame

- (CGRect)titleRectForContentRect:(CGRect)contentRect {

   CGFloat titleY = contentRect.size.height *ZZTabBarImageRatio;

   CGFloat titleH = contentRect.size.height - titleY;

   CGFloat titleW = contentRect.size.width;

   return CGRectMake(0, titleY, titleW,  titleH);

}

 

#pragma mark 设置按钮图片的frame

- (CGRect)imageRectForContentRect:(CGRect)contentRect {

   CGFloat imageH = contentRect.size.height *ZZTabBarImageRatio;

   CGFloat imageW = contentRect.size.width;

   return CGRectMake(0,0, imageW,  imageH);

}

 

- (void)setItem:(UITabBarItem *)item

{

   _item = item;

    

    // 1.利用KVO监听item属性值的改变

    [item addObserver:selfforKeyPath:@"title"options:NSKeyValueObservingOptionNewcontext:nil];

    [item addObserver:selfforKeyPath:@"image"options:NSKeyValueObservingOptionNewcontext:nil];

    [item addObserver:selfforKeyPath:@"selectedImage"options:NSKeyValueObservingOptionNewcontext:nil];

    [item addObserver:selfforKeyPath:@"badgeValue"options:NSKeyValueObservingOptionNewcontext:nil];

    

    // 2.属性赋值

    [selfobserveValueForKeyPath:nilofObject:nilchange:nilcontext:nil];

}

 

/**

 *  KVO监听必须在监听器释放的时候,移除监听操作

 *  通知也得在释放的时候移除监听

 */

- (void)dealloc

{

    [self.itemremoveObserver:selfforKeyPath:@"title"];

    [self.itemremoveObserver:selfforKeyPath:@"image"];

    [self.itemremoveObserver:selfforKeyPath:@"selectedImage"];

    [self.itemremoveObserver:selfforKeyPath:@"badgeValue"];

}

 

/**

 *  监听item的属性值改变

 *

 *  @param keyPath 哪个属性改变了

 *  @param object  哪个对象的属性改变了

 */

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

    [selfsetTitle:self.item.titleforState:UIControlStateNormal];

    [selfsetImage:self.item.imageforState:UIControlStateNormal];

    [selfsetImage:self.item.selectedImageforState:UIControlStateSelected];

    

    // 设置提醒数字

    self.badgeButton.value =self.item.badgeValue;

    CGFloat badgeButtonX =self.frame.size.width -self.badgeButton.frame.size.width -5;

   CGFloat badgeButtonY = 2;

   self.badgeButton.frame =CGRectMake(badgeButtonX, badgeButtonY, 0, 0);

}

@end

 

 

 

 

 

//

//  ZZTabBar.h

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015年 ZZ_Macpro. All rights reserved.

//

 

#import <UIKit/UIKit.h>

 

@class ZZTabBar;

 

@protocol ZZTabBarDelegate <NSObject>

 

@optional

/**

 *  ZZTabBar上面的按钮被选中了

 *

 *  @param tabBar 被点击的ZZTabBar

 *  @param from   原来按钮的位置

 *  @param to     新被选中按钮的位置

 */

- (void)tabBar:(ZZTabBar *)tabBar didSelectedButtonFrom:(NSInteger)from to:(NSInteger)to;

 

/**

 *  ZZTabBar中间的加号按钮被点击了

 */

- (void)tabBarDidClickedPlusButton:(ZZTabBar *)tabBar;

 

@end

 

@interface ZZTabBar :UIView

/**

 *  添加按钮

 *

 *  @param item 模型数据

 */

- (void)addTabBarButtonWithItem:(UITabBarItem *)item;

 

/**

 *  代理 命名以及在理解上需要加强

 */

@property (nonatomic,weak) id<ZZTabBarDelegate> delegate;

 

@end

 

 

//

//  ZZTabBar.m

//  ZZ_APP主流框架

//

//  Created by ZZ_Macpro on 15/9/25.

//  Copyright (c) 2015年 ZZ_Macpro. All rights reserved.

//

 

#import "ZZTabBar.h"

#import "ZZTabBarButton.h"

 

@interface ZZTabBar()

/**

 *  存放tabBar上面的按钮

 */

@property (nonatomic,strong) NSMutableArray *tabBarButtons;

/**

 *  tabBar上被选中的按钮

 */

@property (nonatomic,weak) ZZTabBarButton *selectedButton;

/**

 *  中间增加的加号按钮

 */

@property (nonatomic,weak) UIButton *plusButton;

 

@end

 

@implementation ZZTabBar

 

/**

 *  tabBarButtons懒加载 只初始化一次 不用管他何时创建

 */

- (NSMutableArray *)tabBarButtons

{

    if (_tabBarButtons ==nil) {

        _tabBarButtons = [NSMutableArrayarray];

    }

    return_tabBarButtons;

}

 

/**

 *  初始化 在初始化中添加加号按钮

 */

- (id)initWithFrame:(CGRect)frame

{

   self = [superinitWithFrame:frame];

   if (self) {

       if (!iOS7) {

            self.backgroundColor = [UIColorcolorWithPatternImage:[UIImageimageWithName:@"tabbar_background"]];

        }

        

        [selfaddPlusBtn];

    }

    return self;

}

 

/**

 *  添加+号按钮

 */

- (void)addPlusBtn

{

    // 1.创建按钮

    UIButton *plusButton = [UIButtonbuttonWithType:UIButtonTypeCustom];

    

    // 2.设置背景图片

    UIImage *bg = [UIImageimageWithName:@"tabbar_compose_button"];

    [plusButton setBackgroundImage:bgforState:UIControlStateNormal];

    [plusButton setBackgroundImage:[UIImageimageWithName:@"tabbar_compose_button_highlighted"]forState:UIControlStateHighlighted];

    

    // 3.设置顶部的加号按钮

    [plusButton setImage:[UIImageimageWithName:@"tabbar_compose_icon_add"]forState:UIControlStateNormal];

    [plusButton setImage:[UIImageimageWithName:@"tabbar_compose_icon_add_highlighted"]forState:UIControlStateHighlighted];

    

    // 4.监听按钮点击

    [plusButton addTarget:selfaction:@selector(plusClick)forControlEvents:UIControlEventTouchUpInside];

 

    [selfaddSubview:plusButton];

   /**

     *  对其进行引用后续进行操作

     */

   self.plusButton = plusButton;

}

 

/**

 *  监听加号点击

 */

- (void)plusClick

{

    // 通知代理

   if ([self.delegaterespondsToSelector:@selector(tabBarDidClickedPlusButton:)]) {

        [self.delegatetabBarDidClickedPlusButton:self];

    }

}

 

- (void)addTabBarButtonWithItem:(UITabBarItem *)item

{

    // 1.创建按钮

    ZZTabBarButton *button = [[ZZTabBarButtonalloc] init];

    

    // 2.传递模型数据

    button.item = item;

    

    // 3.添加按钮

    [button addTarget:selfaction:@selector(buttonClick:)forControlEvents:UIControlEventTouchDown];

    [selfaddSubview:button];

    [self.tabBarButtonsaddObject:button];

    

    // 4.默认选中

    if (self.tabBarButtons.count == 1) {

        [selfbuttonClick:button];

    }

}

 

- (void)buttonClick:(ZZTabBarButton *)button

{

    // 0.通知代理

   if ([self.delegaterespondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]) {

        [self.delegatetabBar:selfdidSelectedButtonFrom:self.selectedButton.tagto:button.tag];

    }

    

    // 1.控制器选中按钮

    self.selectedButton.selected =NO;

    button.selected =YES;

   self.selectedButton = button;

}

 

/**

 *  布局子控件

 */

- (void)layoutSubviews

{

    [superlayoutSubviews];

    

    // 1.4个按钮固定的尺寸所以不需要写在循环里面节约性能

   CGFloat buttonW = self.frame.size.width /5;

   CGFloat buttonH = self.frame.size.height;

    

   for (int index =0; index < self.tabBarButtons.count; index++) {

       ZZTabBarButton *button = self.tabBarButtons[index];

        button.tag = index;

       CGFloat buttonX = index * buttonW;

        

       if (index >= 2) {

            buttonX += buttonW;

        }

        //循环一次 值变化一次所以这里才是如何用一个变量 表示出所有的控件

        button.frame =CGRectMake(buttonX, 0, buttonW, buttonH);

    }

    

    // 2.中间的+按钮

    self.plusButton.bounds = (CGRect){CGPointZero,self.plusButton.currentBackgroundImage.size};

    self.plusButton.center =CGPointMake(self.frame.size.width *0.5, self.frame.size.height *0.5);

}

 

@end

 

 

iOS(三)实现App底部TabBar的切换:二 上一篇讲述了iOS自带的TabBar,但在我所见到的很多App源码中大多用了自己写的TabBar,惯例先上图:                     这只是一个最简单的TabBar,但重在原理,虽然是我懒。。。。 HomeViewController.h HomeViewController.m ClassViewController.h ClassV 阅读详情

相关推荐

iOS - 多控制器切换一(巧用tabbarController)

多控制器切换在项目中应用十分广泛 , 市面上的大部分app都能见到其身影 . 首先我认为 , 多控制器的切换 , 应尽量避免一次性加载所有的控制器页面 , 造成内存飙升 , 应尽量满足用到时加载 , 不用时不加载 . 当然也不乏有例外 , 有的时候为了更好的用户体验 , 而页面又较少时 , 可以一次性加载完毕 , 给用户造成一种切换页面加载迅速,不卡顿的假象 , 具体还是看项目需求. 之前

coderMy的博客 5683

猫猫学iOS(四十三)之网易彩票底部自定义TabBar实现切换

猫猫分享,必须精品 原创文章,欢迎转载。转载请注明:翟乃玉的博客 地址:http://blog.youkuaiyun.com/u013357243?viewmode=contents 效果: 代码: NYTabBarController // // NYTabBarController.m // 彩票lottery // // Created by apple o...

weixin_34416649的博客 218

Buttons_tabbar:Flutter程序包,它实现一个TabBar,其中每个标签都是一个切换按钮

Buttons_tabbar:Flutter程序包,它实现一个TabBar,其中每个标签都是一个切换按钮

IOS UITabBar+UINavigation(改变背景/标题文字颜色、状态图片、tabbar选中方形背景、item间距)

基本属性 上导航栏高度:44 状态栏高度:20 下导航栏高度:49 下导航栏图片大小:22px * 22px iOS7新引入的区别 iOS7中系统自带的上下导航栏当没有设置背景图的时候自带半透明+玻璃磨砂效果。这种磨砂效果是很难自己实现的。所以如果想要保留这种效果,就不要自定义上下导航栏。 关于自定义上导航栏的是否是自定义的判断:用手势慢慢切换两个Vi

爱技术....爱生活! 2868

告别Keil!用VSCode+PlatformIO玩转STC单片机(附自动下载配置)

本文详细介绍了如何从Keil迁移到VSCode+PlatformIO进行STC单片机开发,包括环境搭建、自动下载配置等实用技巧。通过对比传统IDE与现代工具链的差异,展示了VSCode+PlatformIO在代码编辑体验、跨平台支持和开发效率上的优势,帮助开发者实现更流畅的STC单片机开发流程。

weixin_27252001的博客 457

国内主流AI编程工具使用实例及总结

AI编程辅助工具是利用人工智能技术来帮助程序员进行软件开发的工具。它们可以在代码编写、代码审查、错误检测、代码优化等多个编程环节发挥作用,提高编程效率和代码质量。通义灵码,基于通义大模型的AI研发辅助工具,提供代码智能生成、研发智能问答、任务自主执行等能力,为开发者带来智能化研发体验,引领AI原生研发新范式。包含智能编码助手和AI程序员。

技术博客 1万+

buttons_tabbar:打造 Flutter 应用中互动性极强的标签栏

buttons_tabbar:打造 Flutter 应用中互动性极强的标签栏 在移动应用开发中,标签栏(TabBar)是一个非常常见的组件,它能帮助用户快速切换不同的页面或视图。今天,我要为大家推荐一个出色的 Flutter 开源项目——buttons_tabbar,它不仅可以为你的应用增添美观的视觉效果,还能提供丰富的交互体验。 项目介绍 buttons_tabbar 是一个开源的 Flutte...

gitblog_00463的博客 421

Clang Static Analyzer 使用教程:本地 + CMake + GitHub Actions 自动静态分析实战

本文介绍了ClangStaticAnalyzer静态代码分析工具的使用方法。该工具基于Clang/LLVM,可检测C/C++代码中的内存泄漏、空指针等常见错误。主要内容包括:安装指南(Ubuntu/macOS/Windows)、命令行使用方法、CMake项目集成方案、GitHub Actions自动化分析配置,以及HTML报告生成与查看。文章还提供了官方资源链接,帮助开发者系统掌握从本地调试到持续集成的完整静态分析工作流,提升代码质量保障能力。适用于需要在开发过程中实施静态分析的C/C++项目。

u014358031的博客 2156

iOS开发-实现自定义Tabbar及tabbar按钮动画效果

INSysTabbar继承UIView,实现tabbarButton效果//代理 @property(nonatomic , strong) UIImage * bgroundImage;//背景图 @property(nonatomic , strong) INSysTabbarShapeView * tabbarBGShapeView;//背景图 @property(nonatomic , strong) UIColor * lineColor;

一名开发者 3233

cadence CIS 库建立--建立自己维护的CIS数据库

遇到一个问题,在使用cadecnce的时候,就是没有自己的本地/分享的数据库。 在画原理图或者PCB的时候,如果能搭建一个自己的数据库,在局域网或者本地 就好了。出于这样的想法,做了一些探索,找到了一种可能的答案。 由于数据库编制知识的缺乏,要自己建一个数据库似乎花费的时间会比较多。 偶发奇想,如果能够改编CIS 自带的数据库 另建立副本进行维护 就能够省下不少麻烦。 先说下CIS 是个啥。网上一搜:总之CIS 是个好东西。 功能强大。 点击CIS capture 中的 Options CIS Config

qq_29776365的博客 2万+

基于互联网的智能旧衣回收箱设计与实现

本文介绍了基于嵌入式系统的智能旧衣回收箱的设计与实现,涵盖了硬件设计、软件开发、图像识别、物联网连接等方面的内容。通过利用最新的技术,如图像识别、物联网和云计算,实现了智能、便捷的旧衣物回收系统。未来,随着技术的不断进步,智能回收系统将会在环保领域发挥更大的作用。

2201_76125393的博客 906

Flutter 基础控件 顶部导航栏 TabBar

Flutter 基础控件 顶部导航栏 TabBar /// 顶部导航栏 demo class TabBarDemo extends StatefulWidget { @override State<StatefulWidget> createState() { return _TabBarDemoState(); } } /// 混入 SingleTickerP...

小小熊的博客 757

【ACP】2025-最新-疑难题解析- 练习二汇总

全球加速是优化公网访问的,负载均衡是分发流量的,公网 NAT 网关是处理公网 IP 的,高速通道是建私网连接但不直接提供固定私网地址功能。C 是客户端加密方式,D 是 ECS 云盘加密,都不属于 OSS 服务器端加密。某企业想使用云服务器 ECS + 负载均衡 SLB + 弹性伸缩 (Auto Scaling) 的架构搭建一个企业级门户网站,技术负责人对于负载均衡和弹性伸缩配合使用没有经验,于是将他理解的两种产品配合使用的一些技术细节列成了一个表单,并请作为架构师的您帮他做一下鉴别,以下哪些项是正确的?

jundao1997的专栏 293

【微信小程序】基础篇 -- 案例 - 自定义 tabBar(四十六)

大家好,又见面了,我是夜阑的狗🐶,本文是专栏【微信小程序开发教程】专栏的第46篇文章;今天开始学习微信小程序的第28天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。 此专栏是我是夜阑的狗微信小程序开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。前面已经介绍了分包-独立分包 & 分包预下载,通过栗子学习了如何设置独立分包以及分包预下载。

JMFive的博客 1万+

[毕设项目-MCP+ENSP]一句话搞定ENSP自动化:MCP + LLM实战(架构图、工具清单、踩坑全解)

用 MCP + LLM 把“人话”变成对华为 ENSP 的安全自动化操作,三款工具覆盖配置/查询/落盘,配套架构、实战与排坑清单。

逐梦苍穹的博客 2537

告别第三方控件!C#实现OPC UA客户端,对接工业设备超简单

C#实现OPC UA客户端无需依赖第三方商业控件,通过快速起步:通过NuGet安装,使用模拟器完成前期开发测试;复用性强:封装通用工具类,支持连接、读写、订阅等核心功能,可直接集成到各类上位机项目;界面友好:通过WinForm绑定工具类,实现可视化操作,适配工业现场人员使用;工业适配:支持安全配置、身份验证,联调步骤清晰,可快速对接西门子、欧姆龙等主流工业设备;稳定性高:具备资源释放、异常处理、线程安全UI更新等特性,满足工业7×24小时运行要求。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1361

ios开发(switf) tabbar页面切换时刷新的方法

tabbar页面切换是不走 override func viewDidLoad() 的, 只有一开始切换的时候会走这个,之后你结构tabbar里面的东西切换的时候都是不会走这个方法的。 所以你需要重写viewWillAppear! 举个例子,重写的写法: override func viewDidLoad() { super.viewDidLoad() self.tableView.rowHeight = 80 let request = NSF

weixin_45564209的博客 2221

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【微信小程序】页面tabBar切换、下拉刷新

在 pages.json 中提供 tabBar 配置,不仅仅是为了方便快速开发导航,更重要的是在App和小程序端提升性能。在这两个平台,底层原生引擎在启动时无需等待js引擎初始化,即可直接读取 pages.json 中配置的 tabBar 信息,渲染原生tab

yzq0820的博客 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

IOS_实现TabBar切换时底部切换效果

1.首先实现代理方法 #pragma mark -- UITabBarControllerDelegate - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { UIImageView* sl

Mark_IOS群组's 专栏 2763

ios tabbar切换,tabbar代码切换,

前言:iOS tabbar切换,tabbar代码切换,  self.tabBarController.selectedIndex = 4;

u014616159的博客 4596

TabBarIOS界面之间切换

知识点学习:React Native常用组件之TabBarIOS和TabBarIOS.Item组件1.代码/** * Sample React Native App * https://github.com/facebook/react-native * @flow */import React, { Component } from 'react'; import { AppReg

2334

iOS开发——代码生成TabBar与视图切换详解

我在之前多篇博客中讲解了在不使用storyboard而使用nib文件的情况下,使用代码生成导航栏并进行跳转,具体可以参考《iOS开发——界面跳转与返回及视图类型详解》《iOS纯代码实现界面建立、跳转、导航栏(无storyboard、无nib)(Objective-C)》。今天我来讲解下在使用nib搭建界面的情况下,用代码生成TabBar,并进行界面之间的跳转。代码示例已经上传至:https://g

乞力马扎罗的雪CYF的博客 5382

自定义TabBarButton

.h -(void)addTabBarButtonWithItem:(UITabBarItem *)itme .m #import "LJFTabbar.h" @implementation LJFTabbar -(void)addTabBarButtonWithItem:(UITabBarItem *)itme{     //1.创建按钮     U

tubiebutu的专栏 555

iOS自定义tabBar

iOS 自定义tabBar

qq_30107193的博客 445

自定义UITabBarController、UITabBar和UIButton

通常情况下,在实际开发过程中经常需要自定义UITabBarController,并且很有可能还涉及到自定义UITabBar和UIButton的情况。就以闲鱼为例,我们尝试着模仿一下它。  为了更好的演示和说明,整个演示项目都将使用纯代码来搭建。所以,来到AppDelegate文件中,实现以下代码:func application(_ application: UIApplication, didFi

Enrica_Shi的博客 2296
上一篇: iOS开发-自定义UIBarButtonItem
下一篇: iOS开发-自定义BadgeButton提醒数字(红色小圆点)
ZZ_iOSDeveloper
博客等级 码龄11年 21粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值