iOS UI进阶-1.1网易彩票框架搭建-代码重构

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

思路:

  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=0; i<count; i++) {
        MJTabBarButton *button=self.subviews[i];
        button.tag=i;

        //设置frame
        CGFloat buttonY=0;
        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 = 0; i<self.viewControllers.count; i++) {
        NSString *name=[NSString stringWithFormat:@"TabBar%d",i+1];
        NSString *selName=[NSString stringWithFormat:@"TabBar%dSel",i+1];
        [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==1) {
        [self buttonClick:button];
    }
}

//该方法通常是设置控件的尺寸,initWithFrame负责创建控件,initWithFrame下的frame是没有值的。
-(void)layoutSubviews
{
    [super layoutSubviews];
    NSUInteger count=self.subviews.count;
    for (NSUInteger i=0; i<count; i++) {
        MJTabBarButton *button=self.subviews[i];
        button.tag=i;

        //设置frame
        CGFloat buttonY=0;
        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;
}

委托页面的完整代码:

//
//  MJTabBarController.m
//  00-ItcastLottery
//
//  Created by apple on 14-4-14.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "MJTabBarController.h"
#import "MJTabBar.h"
//#import "MJTabBarButton.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 = 0; i < self.viewControllers.count; i++) {
        NSString *name = [NSString stringWithFormat:@"TabBar%d", i + 1];
        NSString *selName = [NSString stringWithFormat:@"TabBar%dSel", i + 1];
        [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

最终运行后的效果:

源代码下载:点击下载

时间: 2024-08-25 08:28:44

iOS UI进阶-1.1网易彩票框架搭建-代码重构的相关文章

iOS UI进阶-1.0网易彩票框架搭建

仿网易彩票,最终要做成的效果如下: 一.分层搭建 1.新建一个项目,Lottery.只支持7.1以上坚屏. 2.将素材全部图片全部拉到相应的文件夹里. 3.选中Lottery--右键Show in Finder ,在Lottery文件夹下新建一个Classes,并分别分层成MVC文件夹. 4.把Classes拉到Lottery项目里,整个框架结构如 二.UI搭建 分层好之后,接下来,我们搭建一下界面.使用Storyboard进行搭建. 1.点击Main.storyboard,删除原来的界面,分别

iOS UI进阶-1.3网易彩票设置模块

概述 基本上,每一款APP都有相应的设置模块.怎么设置才能更灵活和通用呢,这也是大家一直思考的.下面说说在网易彩票中,设置模块的设置思想. 基本上有三种方案: static cell(呆板,完全没有动态) 使用代码,条件判断逐个编写(麻烦,代码冗长) 使用plist加载(能够动态配置跳转控制器,不能配置请求代码:由于使用字符串配置跳转控制器名,容易出现运行时错误) 使用模型封装每个cell的数据(item),使用Class作为跳转控制器属性(这样就能经过编译检测) 最终我们使用的是第4种方式来实

iOS UI进阶-1.4网易彩票设置模块二

产品推荐 产品推荐使用的是UICollectionView控件,UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableView 和 UITableViewController 类. 思路: 模型:建立一个MJProduct模型,存放产品的相关信息(标题.图标) 视图:创建xib,继承于UICollectionViewCell 控制器:创建MJProductV

iOS UI进阶-1.2网易彩票常见设置

Navigation导航设置 为了统一管理导航控制器,需要自定义导航控制器MJNavigationController,继承于UINavigationController.分别设置5个Navigation的控制器Class为此控制器. 白色状态栏 统一背景头部导航栏 设置所有Navigation导航栏字体颜色 二级页面隐藏底部导航条 1.白色状态栏.使用application管理状态栏 设置不使用控制器控制状态栏 在MJAppDelegate中设置: - (BOOL)application:(U

IOS Ui控件 修改位置和尺寸,代码添加控件

所有的UI控件最终都继承自UIView,UI控件的公共属性都定义在UIView中, UIView的常见属性 UIView *superview; 获得自己的父控件对象 NSArray *subviews; 获得自己的所有子控件对象 NSInteger tag; 控件的ID(标识),父控件可以通过tag来找到对应的子控件 CGAffineTransform transform; 控件的形变属性(可以设置旋转角度.比例缩放.平移等属性) CGRect frame; 控件所在矩形框在父控件中的位置和尺

[iOS UI进阶 - 2.0] 彩票Demo v1.0

A.需求 1.模仿"网易彩票"做出有5个导航页面和相应功能的Demo 2.v1.0 版本搭建基本框架 B.搭建基本框架 1.拖入TaBarController,5个NavigationController和对应的5个UIViewController 2.配置图标和启动画面 AppIcon直接拖入图片 LaunchImage在Xcode6中需要先更改启动图使用图库的图片,而不是LaunchImage.xib 2.引入图片包 4. 按照模块分类代码包 3.底部导航--自定义TabBar (

[iOS UI进阶 - 2.3] 彩票Demo v1.3

A.需求 真机调试 "关于”模块 存储开关状态 打电话.发短信 应用评分 打开其他应用 cell 在iOS6 和 iOS7的适配 block的循环引用 屏幕适配 code source:  code source: https://github.com/hellovoidworld/HelloLottery B.iOS真机测试小功能 (1)打电话 a.方法1 最简单最直接的方式:直接跳到拨号界面 1 NSURL *url = [NSURL URLWithString:@"tel://1

[iOS UI进阶 - 2.4] 彩票Demo v1.4 转盘动画

A.需求 幸运广场界面中有一个幸运转盘,平时能够自动缓缓转动 能够选择星座 点击“开始选号”开速旋转转盘,旋转一定周数 转盘转动速度节奏:开始-慢-块-慢-结束 设置其余的背景和按钮 code source: 彩票Demo https://github.com/hellovoidworld/HelloLottery 转盘Demo https://github.com/hellovoidworld/LuckyWheelDemo B.实现 1.使用xib设计转盘 2.自定义类 (1)自定义一个继承U

[iOS UI进阶 - 2.1] 彩票Demo v1.1

A.需求 1.优化项目设置 2.自定义导航栏标题按钮 3.多版本处理 4.iOS6和iOS7的适配 5.设置按钮背景 6.设置值UIBarButtonItem样式 B.实现 1.项目配置 (1)程序启动期间隐藏状态栏 (2)程序启动完成显示状态栏 AppDelegate: 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {