首页 > 代码库 > 仿网易彩票思路

仿网易彩票思路

仿网易彩票思路

第一步、 项目的配置
   
1> 新建项目:项目前缀:把项目名称里面的大写抽出来。
   
2> 支持项目部署,支持ios6,ios7
   
3> 不支持横竖屏
   
4> 导入图标和启动图片
   
5> 程序启动的时候,隐藏状态栏,ios6需要恢复状态栏显示
   
6> 设置状态栏颜色 ios7默认状态栏交给控制器管理,修改info.plist文件,让状态栏交给application管理
   
6> 项目文件夹按模块划分,Main:(主框架,自定义tab控制器),Other:存放其他头文件和.m文件(main,代理,pch(头文件))

第二步、 搭建项目主框架
   
1> 修改窗口的根控制器。
       
原因:主窗口的根控制器是TabBar控制器,TabBar里面的子控制器是导航控制器?为什么,因为每个导航条的标题不一样。

第三步、设置tabBar上按钮的图片
   
存在的问题:
   
1> 设置tabBar上面的按钮图片不好使,tabBarButton的图片有规格,用不了。
   
解决方式:
   
1> 自定义tabBar,系统自带的tabBar上的tabBarButton都不好使,自定义的tabBar添加UIButton,注意继承UIView,因为UITabBar里面的子控件根本用不上。
   
2> 自定义tabBar,添加5个按钮,显示图片

    存在的问题?
    
1> tabBar里面的按钮应该由控制器决定
    
2> push控制器的时候底部条,隐藏不了。
    
解决方法:
    
1提供一个方法,给控制器添加按钮。系统自带的tabBar里有多少按钮也是根据控制器个数决定的。
    
2把自定义tabBar添加到系统自带的tabBar

第四步、点击按钮,切换控制器(UITabBarController.selectedIndex
   
存在的问题?
   
1> 只有UITabBarController设置selectedIndex才可以切换控制器,但是UITabBarController不知道当前选中哪个按钮
   
解决方式:
   
2> 用代理或者block把角标传给控制器

第五步、设置导航条的外观(背景图片和文字),只需要设置一次.
   
1> 为什么要获取整个应用程序的导航条外观?避免拿到一个一个导航控制器去设置导航条的外观
   
2> 怎么获取?UINavigationBar *navBar  = [UINavigationBar appearance]只要遵守UIAppearance这个协议,都可以这样获取。
   
3> 设置导航条的背景颜色?ios7ios6是不一样的。
   
4> 运行ios6,适配ios6的导航条。
   
5> ios7ios6导航条图片的区别?
       ios7:
控制器包括状态栏20的高度,导航条的高度为64,会自动把状态栏20的高度填充
       ios6:
状态栏20的高度不属于控制器,导航条高度44。用44高度的图片
   
6> 定义宏,方便适配 #define iOS7 ([[UIDevice currentDevice].systemVersion floatValue] >=7.0)
   
7> 设置导航条文字颜色

第六步、自定义导航控制器
   
1> 为什么要自定义导航控制器?拦截push操作,重写push方法,在push的时候,隐藏底部条,就不需要一个控制器一个控制器的勾选Hide Bottom Bar on Push
   
2> 在自定义导航控制器设置导航条外观
   
3> initialize里设置:导航条外观只需要设置一次
   
4> initialize:在第一次使用这个类或者子类的时候调用
   
5> initialize里判断下是否是本类调用,是才需要设置导航条,保证设置一次主题。self== [ILNavgationController class]

第七步、 完成每个模块的导航条
   
购彩大厅:系统自带的UIBarButton不能同时设置图片和文字,拖一个按钮同时设置文字和图片,还需要设置按钮宽度,资讯和图片中间有间距。
//设置按钮标题的位置
- (
CGRect)titleRectForContentRect:(CGRect)contentRect;
//设置按钮图片的位置
- (
CGRect)imageRectForContentRect:(CGRect)contentRect;
   
合买跟单:titleView需要自定义按钮,设置内部的位置

第八步、自定义按钮:修改内部子控件的尺寸
   
1.获取当前文字:self.currentTitle
   
2.获取当前文字尺寸.计算内部Label的尺寸。
   
3.图片尺寸:假设图片宽度30.w = contentRect.size.width -30
   
注意点:
    * titleRectForContentRect
内部不能调用self.titleLabel,会造成死循环。因为self.titleLabel内部会调用titleRectForContentRect
    * boundingRectWithSize
ios7才有,ios6没有这个方法,需要判断使用。

第九步、 自定义按钮尺寸计算-多版本处理
   
1> 理解编译时报错和运行时报错?#import <Availability.h>
   
2> 运行时报错:在SDK7.0的环境(xcode5)编译boundingRectWithSize,是不会报错的,但是运行在ios6的系统上会报错,ios6没有这个方法。需要判断当前运行在哪个系统,用ios7宏判断。
   
3> 编译时报错:在SDK6.0的环境(xcode4.6)编译boundingRectWithSize,是直接报编译错误,因为sdk6.0没有这个方法。

第十步、 我的彩票(登录界面)-ios7ios6简单适配
   
存在问题
   
1> 观察UIImageViewy
   
1> UIImageViewy值在ios6ios7不一样。
   
原因:
   
0> ios6,ios7控制器view的尺寸不一样。
   
1> ios6里主流框架中,导航控制器的根控制器view的尺寸,很小。PPT演示,ios6控制器从导航条开始,ios7从屏幕左上角开始,包含状态栏。
   
2> ios7多了一个edgesForExtendedLayout属性,才让导航控制器的根控制器view的尺寸和屏幕一样大.
   
3> edgesForExtendedLayout可以让控制器上下左右扩展
   
解决:
   
1> 通过代码判断下,调整在ios7ios6UIImageView的位置,这种方式麻烦。因为界面是固定的,用xib或者storyboard描述更省时间。
   
2> 找到我的彩票控制器,告诉他不要上下扩展就好了,找到Extend Edages,把Under Top Bars Under Bottom Bars取消选中
   
2> 一般开发中,如果不需要滚动的控制器,就不需要扩展,因为不需要有穿透效果。
   
3> ios7取消我的彩票控制器的上下扩展。这时候ios7导航控制器的根控制器view的尺寸就和ios6一样的了。
   
4> autolayout解决运行在3.5上图片被压扁。

13>登录按钮图片拉伸(按钮尺寸:300* 40
   
1> 拉伸图片中间一个像素点。
   
2> 通过storyboard只能拉伸UIImageView
   
3> storyboardx:表示左边多少不拉伸y:表示上边多少不拉伸w:表示宽度拉伸多少个像素h:表示高度拉伸多少个像素x:0.5(左边一半不拉伸) y:0.5(顶部一半不拉伸) w:0(宽度拉伸一个像素) h:0(高度拉伸一个像素)
   
4> 拉伸按钮,必须通过代码。
   
5> 自定义登录控制器loginController
   
6> UIImage抽分类resizableImageWithName

14>我的彩票(右上角设置按钮的颜色和返回按钮的颜色默认是蓝色,需要设置为白色)
   
1> 应用程序所有导航条上的UIBarButton都需要设置白色的。
   
2> UIBarButton在导航条上,所以我们设置导航条的主题颜色就好了。
   
3> 获取整个应用程序的外观设置主题颜色 UINavigationBar setTintColor(主题颜色)
   
3> 只需要设置一次,并且跟导航控制器有关系,在导航控制器里的initialize里设置,并且之前在导航控制器拿到了整个应用程序的导航条

15>设置ios6上应用程序所有导航条上的按钮背景
   
1> 导航条白色主题只有在ios7才需要设置。
   
2> 设置导航条上的UIBarButton背景,只有在ios6才需要设置
   
3> UIBarButtonUIBarButtonItem决定。
   
4> 获取整个应用程序的UIBarButtonItem,设置整个应用程序的UIBarButton。避免一个控制器一个控制器的设置
   
5> UIBarButtonItem setBackgroundImage //设置按钮背景
   
6> UIBarButtonItem setBackButtonBackgroundImage//设置返回按钮背景


/*彩票第二天*/
1>搭建设置界面分析
   
1> 静态单元格:一个cell一个cell的改,太麻烦,而且不灵活
   
2> plist文件:配置plist文件太费时间

2>自定义设置控制器(代码跳转)
   
1> group样式
   
2> 分析数据结构:大数组里面存放两个小数组,小数组存放每一行的模型
   
3> 实现数据源方法
    *
大数组:告诉tableView有多少组tableView:numberOfSectionsInTableView:
    *
小数组:告诉tableView每一组有多少行tableView:numberOfRowsInSection:
    *
小数组里存:每一行长什么样tableView:cellForRowAtIndexPath:
3>自定义cell模型,ILSettingItem(title,icon)
   
1> 运用模型,展示tableView数据

4> tableView里面的所有显示都交给模型去管理?怎么做
   
1> 自定义组模型,ILSettingGroup(header,footer,items):每一组有头部标题和尾部标题和有多少行cell

5>模型差不多设计好了,该封装视图了。设计步骤:先设计模型,在封装视图。因为视图是根据模型展示的。
   
1> 自定义cell,传一个模型,就展示数据。
   
2> accessoryView:由模型决定。tableView上的所有显示,由模型决定。
   
3> item模型添加一个枚举。不够面向对象,应该把每一个cell的类型都对应一个模型,因为不同的cell类型不同的操作。箭头的cell一般需要跳转,开关的不需要跳转。箭头应该比开关多添加一个属性,跳转的控制器类型Class
   
4> 自定义箭头模型(ILSettingArrowItem),继承ILSettingItem,添加一个跳转的控制器的属性,并提供一个类方法
       
1> Class assign 因为不是都系类型,不需要管理内存在的问题
       
2> 为什么用Class,因为Class写错类型就会报错。
   
5> 自定义开关模型(ILSettingSwitchItem),继承ILSettingItem

6>设置cellaccessoryView
   
1> 完善tableView模型,弄真实数据。
   
2> 在重写set模型的方法里,根据item的类型判断cell上显示什么样的accessoryView
   
3> cell懒加载UIImageViewUISwitch,注意用strong,否则会被销毁,没有其他视图强引用他,没有addSubviews
   
4> 总结:只要没有add的控件,都需要强引用

7>完善cell的跳转功能
   
1> 点击cell就跳转
   
2> 实现tableView代理方法didSelectRowAtIndexPath
       
1.根据模型判断是否需要跳转
       
2.是否有destVcClass属性
       
3.通过类名创建控制器对象,跳转。[[arrowItem.destVcClass alloc] init];


8>检查新版本cell(完善cell操作功能)
   
1> 点击更新cell,做一些事情,而不是跳转,怎么做?
   
2> 最蠢的办法根据角标去判断,点击了哪一行
   
3> 更新操作交给模型去管理。让模型保存一个功能,功能及代码。
   
4> 怎么保存代码?ILSettingItem添加一个block属性,用block保存一段代码.
   
5> 每一行cell应该都会有操作,因此给ILSettingItem添加block属性,这样子类都有这个block属性
   
6> 完善更新模型
       
1. 思路:只有服务器才知道是否有最新数据,因此需要发送网络请求
       
2. 更新功能步骤:发送网络请求(当前手机版本) -> 服务器返回数据(是否需要更新) -> 弹框提示用户。
       
3. 如果需要更新跳到appstory更新
   
7> 点击cell的时候调用block
   
8> 更新cell一直选中状态,应该点击一行的时候,立即取消

9>产品推荐(UICollectionViewController)
   
1> 使用UICollectionViewController,跳入头文件,发现和UITableViewController一样,有数据源和代理
   
2> UITableView每一行是UITableViewCell,UICollectionView每一个是UICollectionViewCell
   
2> 实现数据源,
        * numberOfSectionsInCollectionView
返回UICollectionView有多少组
        * numberOfItemsInSection
返回一组多少个
        * cellForItemAtIndexPath 
返回一个cell长什么样
   
3> 解释section,item,循环利用。section:哪一组  item:哪一个
   
4> 怎么使用UICollectionViewCell?必须先注册,init方法没有提供标识符的构造方法
   
5> 注册cell,在viewDidLoad注册一次
   
6> 必须传入布局,告诉他怎么布局。这么多格子,他怎么知道怎么布局啊。
   
7> 使用流水布局 UICollectionViewFlowLayout ,封装到控制器里面
   
8> 怎么设置UICollectionViewCell的尺寸和位置,通过layout布局设置

10>完成产品推荐(分析产品json数据)以后的思路都是这样的,
   
思路:解析数据,转换模型,描述界面,传递模型给界面,展示到视图。
   
1> 解析json数据,json最外面是[],表示这是个json数组,解析出来也是数组
   
2> 创建模型,提供类方法,不能用KVCid比较特殊
   
3> 自定义cell,传递模型
   
4> 注册xibcell
   
5> 设置cellUIImageView的圆角属性,设置cell的尺寸。
   
6> 监听点击
   
7> 导航条的标题:在push之前的时候就设置,拿到模型的title直接设置vc.title = arrowItem.title;

10>推送和提醒模块(抽取父控制器)
   
1> 分析界面外观:跟设置界面一样的cell,只需要给cell传递一个模型,就自动生成一个界面了。
   
2> 配置模型
   
3> 抽取父控制器ILBaseTableViewController
   
4> 配置中奖提醒,中奖动画,比分直播(ILAwardPushViewController,ILAwardAnimationViewController,ILScorNoticeViewController)
   
5> ILScorNoticeViewController控制器比较特殊,cell右边有label
   
6> 根据模型,显示cell
   
7> 自定义ILSettingLabelItem,添加text属性,用于显示label文字
   
8> 修改ILSettingCell,根据模型,判断是否懒加载UILabel,label必须设置尺寸
   
9> 配置比分直播的模型

11>比分直播label处理
   
1> 从下往上钻的是什么?键盘才有这样的效果,也就是点击label弹出键盘
   
2> 什么东西能弹出键盘?textField成为第一响应者
   
3> 创建一个textField,不需要显示,目的就是弹出键盘
   
4> 修改键盘inputViewUIDatePicker
        *
设置UIDatePicker的默认时间
           
// 日期格式对象
            NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
            fmt.dateFormat =
@"HH:mm";
           
// 字符串转日期
            NSDate *date = [fmt dateFromString:_startItem.text];
            _datePicker.date = date;

        * UIDatePicker
的模式
           
// 模式
            _datePicker.datePickerMode = UIDatePickerModeTime;

        * UIDatePicker
的地区
           
// 地区
            _datePicker.locale = [NSLocale localeWithLocaleIdentifier:
@"zh_CN"];
   
5> 监听UIDatePicker的滚动,改变ILSettingLabelItem的值
        *
日期转字符串
            NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
            fmt.dateFormat =
@"HH:mm";

            _startItem.text = [fmt stringFromDate:datePicker.date];
   
6> 刷新表格,更新界面

12>数据存储
   
1> 存储cellaccessoryView的状态,用[NSUserDefaults standardUserDefaults]快速存储,别忘记同步synchronize
   
2> ILSettingLabelItemtext
        *
重写模型setText方法,在设置的text的时候就存储。
        * key:
用模型的title属性,目的知道是哪个cell存储了,每个cell都有title
   
3> ILSettingSwitchItem开关的状态
        *
监听switch的改变
        *
给模型添加一个属性,开关属性off
        *
重写setOff方法,设置的时候就存储
   
4> 怎么读取,重写两个模型的setTitle方法,在设置title的时候就读取一次,给对应的属性赋值。
            * ILSettingLabelItem
存储代码
            - (
void)setTitle:(NSString *)title
            {
               
// 这里不能拿到_title赋值,只能调用父类的set方法赋值
                [
supersetTitle:title];
               
                _text = [ILSettingTool objectForKey:
self.title];
               
            }
            - (
void)setTitle:(NSString *)title
            {
               
// 这里不能拿到_title赋值,只能调用父类的set方法赋值
                [
supersetTitle:title];
               
                _off = [ILSettingTool boolForKey:
self.title];
               
            }

            * ILSettingSwitchItem
存储代码
                - (
void)setOff:(BOOL)off
                {
                    _off = off;
                   
                    [ILSettingTool setBool:off forKey:
self.title];
                }

                - (
void)setTitle:(NSString *)title
                {
                   
// 这里不能拿到_title赋值,只能调用父类的set方法赋值
                    [
supersetTitle:title];
                   
                    _off = [ILSettingTool boolForKey:
self.title];
                   
                }

仿网易彩票思路