在上一篇中,我们基本已经把整个框架都搭建出来了,下面进行代码重构一下。

思路:

  1. 导航按钮,按下时,会变灰,那是系统自带了,通过自定义UIButton,实现按下按钮立即切换效果。
  2. MJTabBarController管得太多了,只需要传图片过去,即创建好一个TabBar.
  3. 通过代理实现底部tabbar的切换。

一.自定义UIButton,继承自UIButton。MJTabBarButton.m

#import "MJTabBarButton.h"

@implementation MJTabBarButton

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
} /**
* 只要覆盖了这个方法,按钮就不存在高亮状态
*/
- (void)setHighlighted:(BOOL)highlighted
{
//
}
@end

二.定义一个View,封装创建tarbar按钮的方法。

MJTabBar.h

#import <UIKit/UIKit.h>

@interface MJTabBar : UIView
-(void)addTabBarWithName:(NSString *)name selName:(NSString *)selName;
@end

MJTabBar.m

//
// MJTabBar.m
// Lottery
//
// Created by jiangys on 15/8/30.
// Copyright (c) 2015年 weconex. All rights reserved.
// #import "MJTabBar.h"
#import "MJTabBarButton.h" @implementation MJTabBar //创建tabBar按钮
-(void)addTabBarWithName:(NSString *)name selName:(NSString *)selName
{
MJTabBarButton *button=[MJTabBarButton buttonWithType:UIButtonTypeCustom]; //设置图片
[button setBackgroundImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:selName] forState:UIControlStateSelected]; //添加
[self addSubview:button];
} //该方法通常是设置控件的尺寸,initWithFrame负责创建控件,initWithFrame下的frame是没有值的。
-(void)layoutSubviews
{
[super layoutSubviews];
NSUInteger count=self.subviews.count;
for (NSUInteger i=; i<count; i++) {
MJTabBarButton *button=self.subviews[i];
button.tag=i; //设置frame
CGFloat buttonY=;
CGFloat buttonW=self.frame.size.width/count;
CGFloat buttonH=self.frame.size.height;
CGFloat buttonX=i*buttonW;
button.frame=CGRectMake(buttonX, buttonY, buttonW, buttonH);
}
} @end

那么,MJTabBarController.m里加载底部的tabBar就很简单了

//
// MJTabBarController.m
// Lottery
//
// Created by apple on 15/8/27.
// Copyright (c) 2015年 weconex. All rights reserved.
// #import "MJTabBarController.h"
#import "MJTabBar.h" @interface MJTabBarController ()@end @implementation MJTabBarController - (void)viewDidLoad {
[super viewDidLoad]; // 1.添加自己的tabbar
MJTabBar *myTabBar = [[MJTabBar alloc] init];
myTabBar.frame = self.tabBar.bounds;
[self.tabBar addSubview:myTabBar]; // 2.添加5个按钮
for (int i = ; i<self.viewControllers.count; i++) {
NSString *name=[NSString stringWithFormat:@"TabBar%d",i+];
NSString *selName=[NSString stringWithFormat:@"TabBar%dSel",i+];
[myTabBar addTabBarWithName:name selName:selName];
}
}
@end

运行后的效果:

目前还不能点击底部的那几个tarBar按钮,拉下来,我们通过代理的方式来实现。

三.通过代理方式实现底部按钮点击切换

1.定义协议。在MJTabBar.h文件最上边声明协议

@class MJTabBar;

@protocol MJTabBarDelegate <NSObject>
-(void)tabBar:(MJTabBar *)tabBar didSelectButtonFrom:(int)from to:(int)to;
@end

2.定义代理。继续在MJTabBar.h中声明一个委托的变量

//声明委托变量
@property(nonatomic,weak)id<MJTabBarDelegate> delegate;

MJTabBar.h完整代码

#import <UIKit/UIKit.h>
@class MJTabBar; @protocol MJTabBarDelegate <NSObject>
-(void)tabBar:(MJTabBar *)tabBar didSelectButtonFrom:(int)from to:(int)to;
@end @interface MJTabBar : UIView
//声明委托变量
@property(nonatomic,weak)id<MJTabBarDelegate> delegate;
-(void)addTabBarWithName:(NSString *)name selName:(NSString *)selName;
@end

3.通知代理。在MJTabBar.m完整代码

//
// MJTabBar.m
// Lottery
//
// Created by jiangys on 15/8/30.
// Copyright (c) 2015年 weconex. All rights reserved.
// #import "MJTabBar.h"
#import "MJTabBarButton.h" @interface MJTabBar()
/**
* 记录当前选中的按钮
*/
@property (nonatomic, weak) UIButton *selectedButton;
@end @implementation MJTabBar //创建tabBar按钮
-(void)addTabBarWithName:(NSString *)name selName:(NSString *)selName
{
MJTabBarButton *button=[MJTabBarButton buttonWithType:UIButtonTypeCustom]; //设置图片
[button setBackgroundImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:selName] forState:UIControlStateSelected]; //添加
[self addSubview:button]; //监听
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown]; //默认选中第0个按钮
if (self.subviews.count==) {
[self buttonClick:button];
}
} //该方法通常是设置控件的尺寸,initWithFrame负责创建控件,initWithFrame下的frame是没有值的。
-(void)layoutSubviews
{
[super layoutSubviews];
NSUInteger count=self.subviews.count;
for (NSUInteger i=; i<count; i++) {
MJTabBarButton *button=self.subviews[i];
button.tag=i; //设置frame
CGFloat buttonY=;
CGFloat buttonW=self.frame.size.width/count;
CGFloat buttonH=self.frame.size.height;
CGFloat buttonX=i*buttonW;
button.frame=CGRectMake(buttonX, buttonY, buttonW, buttonH);
}
} /**
* 监听按钮点击
*/
-(void)buttonClick:(UIButton *)button
{
//通知代理
if ([self.delegate respondsToSelector:@selector(tabBar:didSelectButtonFrom:to:)]) {
[self.delegate tabBar:self didSelectButtonFrom:self.selectedButton.tag to:button.tag];
} // 1.让当前选中的按钮取消选中
self.selectedButton.selected = NO; // 2.让新点击的按钮选中
button.selected = YES; // 3.新点击的按钮就成为了"当前选中的按钮"
self.selectedButton = button;
} @end

4.委托页面,实现代理协议。MJTabBarController.m 实现

@interface MJTabBarController () <MJTabBarDelegate>
@end

5.委托页面,先让自己成为代理,并实现代理方法。MJTabBarController.m 实现:

 myTabBar.delegate = self;
- (void)tabBar:(MJTabBar *)tabBar didSelectButtonFrom:(int)from to:(int)to
{
// 选中最新的控制器
self.selectedIndex = to;
}

委托页面的完整代码:

#import "MJTabBarController.h"
#import "MJTabBar.h" @interface MJTabBarController () <MJTabBarDelegate>
@end @implementation MJTabBarController - (void)viewDidLoad
{
[super viewDidLoad]; // 1.添加自己的tabbar
MJTabBar *myTabBar = [[MJTabBar alloc] init];
myTabBar.delegate = self;
myTabBar.frame = self.tabBar.bounds;
[self.tabBar addSubview:myTabBar]; // 2.添加对应个数的按钮
for (int i = ; i < self.viewControllers.count; i++) {
NSString *name = [NSString stringWithFormat:@"TabBar%d", i + ];
NSString *selName = [NSString stringWithFormat:@"TabBar%dSel", i + ];
[myTabBar addTabButtonWithName:name selName:selName];
}
} /**
normal : 普通状态
highlighted : 高亮(用户长按的时候达到这个状态)
disable : enabled = NO
selected : selected = YES
*/ #pragma mark - MJTabBar的代理方法
- (void)tabBar:(MJTabBar *)tabBar didSelectButtonFrom:(int)from to:(int)to
{
// 选中最新的控制器
self.selectedIndex = to;
}
@end

最终运行后的效果:

源代码下载:点击下载

iOS 网易彩票-2框架搭建-代码重构的更多相关文章

  1. iOS 网易彩票-1框架搭建

    仿网易彩票,最终要做成的效果如下: 一.分层搭建 1.新建一个项目,Lottery.只支持7.1以上坚屏. 2.将素材全部图片全部拉到相应的文件夹里. 3.选中Lottery--右键Show in F ...

  2. iOS 网易彩票-6设置模块三(常用小功能)

    该篇文章中,用到很多iOS开发过程中常用的小功能,当前只是将这些功能集成到网易彩票的设置中.iOS-常用小功能介绍,请参考我的另一篇文章: iOS 常用小功能 总结:http://www.cnblog ...

  3. iOS 网易彩票-4设置模块一

    概述 基本上,每一款APP都有相应的设置模块.怎么设置才能更灵活和通用呢,这也是大家一直思考的.下面说说在网易彩票中,设置模块的设置思想. 基本上有三种方案: static cell(呆板,完全没有动 ...

  4. iOS 网易彩票-5设置模块二

    产品推荐 产品推荐使用的是UICollectionView控件,UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视 ...

  5. iOS 网易彩票-3常见设置

    Navigation导航设置 为了统一管理导航控制器,需要自定义导航控制器MJNavigationController,继承于UINavigationController.分别设置5个Navigati ...

  6. Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介

    约定 还记得上版本的第二十四篇的约定嘛?现在出来履行啦~ 为什么要重制? 之前写的专栏都是按照心情写的,在最初的时候笔者什么都不懂,而且文章的发布是按照很随性的一个顺序.结果就是说,大家都看完了,都还 ...

  7. 再造轮子之网易彩票-第一季(IOS 篇 by sixleaves)

    前言 在网上看了别人做的模仿网易彩票的项目, 于是也跟着用自己的想法做了一篇.写这篇博客的目的, 在于UI综合的一次小练习, 同时总结和串联其各个控件之间的应用.封装思想等.考虑到有人上不了githu ...

  8. iOS项目——基本框架搭建

    项目开发过程中,在完成iOS项目——项目开发环境搭建之后,我们首先需要考虑的就是我们的项目的整体框架与导航架构设计,然后在这个基础上考虑功能模块的完成. 一 导航架构设计 一款App的导航架构设计应该 ...

  9. iOS 从零到一搭建组件化项目框架

    随着公司业务需求的不断迭代发展,工程的代码量和业务逻辑也越来越多,原始的开发模式和架构已经无法满足我们的业务发展速度了,这时我们就需要将原始项目进行一次重构大手术了.这时我们应该很清晰这次手术的动刀口 ...

随机推荐

  1. Tomorrow Is A New Day

    Sometimes we do not feel like we want to feel     Sometimes we do not achieve what we want to achiev ...

  2. u-boot.lds文件简介

    可执行文件由许多链接在一起的对象文件组成.对象文件有许多节,如文本.数据.init 数据.bss等.这些对象文件都是由一个称为 链接器脚本(*lds)的文件链接并装入的.这个链接器脚本的功能是将输入对 ...

  3. 原生js--跨域消息传递

    跨域消息传递:postMessage() 1.兼容性问题:IE8及其以上浏览器和其它主流浏览器都已经支持 2.使用范围:跨iframe.跨页面.跨域 3.使用方法: 发送消息:postMessage( ...

  4. storm事务

    1. storm 事务 对于容错机制,Storm通过一个系统级别的组件acker,结合xor校验机制判断一个msg是否发送成功,进而spout可以重发该msg,保证一个msg在出错的情况下至少被重发一 ...

  5. Elasticsearch学习之嵌套聚合,下钻分析,聚合分析

    1. 计算每个tag下的商品数量 GET /ecommerce/product/_search { "aggs": { "group_by_tags": { & ...

  6. intelj idea编译项目报错,Error:ajc: The method getDestHost() is undefined

    一.问题简述 这两天在idea中引入过aspectJ相关的东西,用到了aspectJ的编译器进行编译时织入. 结果今天在编译一个老项目时,(用到了lombok,lombok的idea插件会在javac ...

  7. Struts2之命名空间与Action的三种创建方式

    看到上面的标题,相信大家已经知道我们接下来要探讨的知识了,一共两点:1.package命名空间设置:2.三种Action的创建方式.下面我们开始本篇的内容: 首先我们聊一聊命名空间的知识,namesp ...

  8. [转]Windows上搭建Kafka运行环境

    [转]http://www.cnblogs.com/alvingofast/p/kafka_deployment_on_windows.html Windows上搭建Kafka运行环境   完整解决方 ...

  9. [工具] 知网(CNKI)文献下载工具

    https://github.com/amyhaber/cnki-downloader 用于免费搜索,下载CNKI上的各类文献资料

  10. spring boot 通过Maven + tomcat 自动化部署

    使用maven创建的springboot项目,默认是jar包,springboot还有自己带的tomcat. 现在为了简单实现本地自动发布项目到服务器,需要通过发布war包的形式,通过maven将项目 ...