概述

基本上,每一款APP都有相应的设置模块。怎么设置才能更灵活和通用呢,这也是大家一直思考的。下面说说在网易彩票中,设置模块的设置思想。

基本上有三种方案:

  1. static cell(呆板,完全没有动态)
  2. 使用代码,条件判断逐个编写(麻烦,代码冗长)
  3. 使用plist加载(能够动态配置跳转控制器,不能配置请求代码;由于使用字符串配置跳转控制器名,容易出现运行时错误)
  4. 使用模型封装每个cell的数据(item),使用Class作为跳转控制器属性(这样就能经过编译检测)

最终我们使用的是第4种方式来实现,效果:

实现

思路:

1.创建cell的数据模型group(头部标题、尾部标题及items)

2.创建cell的数据模型item(图标、标题、block、跳转到控制器)

3.自定义cell,根据不同的item模型创建不同的cell外观(箭头、开头、文本等)

4.自定一个基类控制器,实现

  • 加载解析group和item数据
  • 根据group数据创建table的样式(组底部、组尾部)
  • 加载自定义的cell
  • 如果item类是跳转类型的,需要配置跳转目标控制器
  • 如果item类是代码执行型的,需要配置要执行的block代码

5.设置界面实现基类控制器,只需要简单配置要显示的item

创建cell的数据模型group

MJSettingGroup.h

#import <Foundation/Foundation.h>

@interface MJSettingGroup : NSObject

/** 头部标题*/
@property (nonatomic, copy) NSString *header;
/** 尾部标题*/
@property (nonatomic, copy) NSString *footer;
/** 存放这组行的所有的模型*/
@property (nonatomic, copy) NSArray *items; @end

创建cell的数据模型item

    

单元Cell中有好几种类型:

  • 开头
  • 箭头
  • 文本

因此,为了在界面上更容易区别,我们分别为这几个类型定义一个模型。当前,这几种类型的中,左边显示图标和不显示图标都是一样的,因此,定义一个单元Cell模型基类,其它都继续于这个基类。

(基类)MJSettingItem.h

#import <Foundation/Foundation.h>

typedef void (^MJSettingItemOption)();

@interface MJSettingItem : NSObject

/**    图标    */
@property (nonatomic, copy) NSString *icon;
/** 标题 */
@property (nonatomic, copy) NSString *title;
/** 点击cell要做的事情 */
@property (nonatomic, copy) MJSettingItemOption option; +(instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title;
+(instancetype)itemWithTitle:(NSString *)title;
@end

(基类)MJSettingItem.m

#import "MJSettingItem.h"

@implementation MJSettingItem

+(instancetype)itemWithTitle:(NSString *)title
{
return [self itemWithIcon:nil title:title];
} +(instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title
{
MJSettingItem *item = [[self alloc] init];
item.icon = icon;
item.title = title;
return item;
} @end

MJSettingLabelItem(文本)、MJSettingSwitchItem(开关)、MJSettingArrowItem(箭头)都分别继承MJMJSettingItem

MJSettingArrowItem.h

#import "MJSettingItem.h"

@interface MJSettingArrowItem : MJSettingItem
/**
* 点击这行cell需要跳转的控制器
*/
@property (nonatomic, assign) Class destVcClass; + (instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title destVcClass:(Class)destVcClass;
+ (instancetype)itemWithTitle:(NSString *)title destVcClass:(Class)destVcClass; @end

MJSettingArrowItem.m

#import "MJSettingArrowItem.h"

@implementation MJSettingArrowItem

+ (instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title destVcClass:(Class)destVcClass
{
MJSettingArrowItem *item = [self itemWithIcon:icon title:title];
item.destVcClass = destVcClass;
return item;
} + (instancetype)itemWithTitle:(NSString *)title destVcClass:(Class)destVcClass
{
return [self itemWithIcon:nil title:title destVcClass:destVcClass];
} @end

自定义cell

需要根据模型来给每个cell设置数据和类型,因而,通过自定义cell来实现。分别指定显示的数据和右边显示的内容类型。

MJSettingCell.h

#import <UIKit/UIKit.h>

@class MJSettingItem;

@interface MJSettingCell : UITableViewCell
/**
* 每个cell需要显示的数据
*/
@property (nonatomic, strong) MJSettingItem *item; + (instancetype)cellWithTableView:(UITableView *)tableView; @end

MJSettingCell.m

//
// MJSettingCell.m
// Lottery
//
// Created by apple on 15/9/6.
// Copyright (c) 2015年 weconex. All rights reserved.
// #import "MJSettingCell.h"
#import "MJSettingItem.h"
#import "MJSettingSwitchItem.h"
#import "MJSettingArrowItem.h"
#import "MJSettingLabelItem.h" @interface MJSettingCell()
/** 箭头*/
@property (nonatomic, strong) UIImageView *arrowView;
/** 开关*/
@property (nonatomic, strong) UISwitch *switchView;
/** 标签*/
@property (nonatomic, strong) UILabel *labelView;
@end @implementation MJSettingCell //懒加载,所有的箭头都只加载一次
- (UIImageView *)arrowView
{
if (_arrowView == nil) {
_arrowView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellArrow"]];
}
return _arrowView;
} //懒加载,所有的开关都只加载一次
- (UISwitch *)switchView
{
if (_switchView == nil) {
_switchView = [[UISwitch alloc] init];
}
return _switchView;
} //懒加载,所有的文本都只加载一次
- (UILabel *)labelView
{
if (_labelView == nil) {
_labelView = [[UILabel alloc] init];
_labelView.bounds = CGRectMake(, , , );
_labelView.backgroundColor = [UIColor redColor];
}
return _labelView;
} + (instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"setting";
MJSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[MJSettingCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
return cell;
} /**
* 重写定义的属性item的Set方法,只有赋值就设定数据
*/
- (void)setItem:(MJSettingItem *)item
{
_item = item; // 1.设置数据
[self setupData]; // 2.设置右边的内容
[self setupRightContent];
} /**
* 设置右边的内容
*/
- (void)setupRightContent
{
if ([self.item isKindOfClass:[MJSettingArrowItem class]]) { // 箭头
self.accessoryView = self.arrowView;
} else if ([self.item isKindOfClass:[MJSettingSwitchItem class]]) { // 开关
self.accessoryView = self.switchView;
self.selectionStyle = UITableViewCellSelectionStyleNone;
} else if ([self.item isKindOfClass:[MJSettingLabelItem class]]) { // 标签
self.accessoryView = self.labelView;
} else {
self.accessoryView = nil;
}
} /**
* 设置数据
*/
- (void)setupData
{
if (self.item.icon) {
self.imageView.image = [UIImage imageNamed:self.item.icon];
}
self.textLabel.text = self.item.title;
} @end

自定一个基类控制器,实现

  • 加载解析group和item数据
  • 根据group数据创建table的样式(组底部、组尾部)
  • 根据不同的item模型创建不同的cell外观(箭头、开头、文本等)
  • 如果item类是跳转类型的,需要配置跳转目标控制器
  • 如果item类是代码执行型的,需要配置要执行的block代码

MJBaseSettingViewController.h

#import <UIKit/UIKit.h>

@interface MJBaseSettingViewController : UITableViewController
@property (nonatomic, strong) NSMutableArray *data;
@end

MJBaseSettingViewController.m

//
// MJBaseSettingViewController.m
// Lottery
//
// Created by apple on 15/9/6.
// Copyright (c) 2015年 weconex. All rights reserved.
// #import "MJBaseSettingViewController.h"
#import "MJSettingArrowItem.h"
#import "MJSettingSwitchItem.h"
#import "MJSettingGroup.h"
#import "MJSettingCell.h" @interface MJBaseSettingViewController ()
@end @implementation MJBaseSettingViewController - (id)init
{
return [super initWithStyle:UITableViewStyleGrouped];
} - (id)initWithStyle:(UITableViewStyle)style
{
return [super initWithStyle:UITableViewStyleGrouped];
} - (NSArray *)data
{
if (_data == nil) {
_data = [NSMutableArray array];
}
return _data;
} #pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.data.count;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
MJSettingGroup *group = self.data[section];
return group.items.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
MJSettingCell *cell = [MJSettingCell cellWithTableView:tableView]; // 2.给cell传递模型数据
MJSettingGroup *group = self.data[indexPath.section];
cell.item = group.items[indexPath.row]; // 3.返回cell
return cell;
} - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.取消选中这行
[tableView deselectRowAtIndexPath:indexPath animated:YES]; // 2.模型数据
MJSettingGroup *group = self.data[indexPath.section];
MJSettingItem *item = group.items[indexPath.row]; if (item.option) { // block有值(点击这个cell,.有特定的操作需要执行)
item.option();
} else if ([item isKindOfClass:[MJSettingArrowItem class]]) { // 箭头
MJSettingArrowItem *arrowItem = (MJSettingArrowItem *)item; // 如果没有需要跳转的控制器
if (arrowItem.destVcClass == nil) return; UIViewController *vc = [[arrowItem.destVcClass alloc] init];
vc.title = arrowItem.title;
[self.navigationController pushViewController:vc animated:YES];
}
} /**
* 头部标题
*/
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
MJSettingGroup *group = self.data[section];
return group.header;
} /**
* 底部标题
*/
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
MJSettingGroup *group = self.data[section];
return group.footer;
}
@end

设置界面实现

实现基类控制器,只需要简单配置要显示的cell的文字,图片,push的控制器或者要执行的block代码。

MJSettingViewController.m

//
// MJSettingViewController.m
// Lottery
//
// Created by apple on 15/9/6.
// Copyright (c) 2015年 weconex. All rights reserved.
// #import "MJSettingViewController.h"
#import "MJSettingArrowItem.h"
#import "MJSettingSwitchItem.h"
#import "MJSettingGroup.h"
#import "MJTest1ViewController.h" @interface MJSettingViewController ()
@end @implementation MJSettingViewController
/**
* 第1组数据
*/
- (void)setupGroup1
{
MJSettingItem *update = [MJSettingArrowItem itemWithIcon:@"MoreUpdate" title:@"检查新版本"];
update.option = ^{
// 弹框提示
NSLog(@"正在检查更新");
};
MJSettingItem *help = [MJSettingArrowItem itemWithIcon:@"MoreHelp" title:@"帮助" destVcClass:[MJTest1ViewController class]];
MJSettingItem *share = [MJSettingArrowItem itemWithIcon:@"MoreShare" title:@"分享" destVcClass:[MJTest1ViewController class]];
MJSettingItem *viewMsg = [MJSettingArrowItem itemWithIcon:@"MoreMessage" title:@"查看消息" destVcClass:[MJTest1ViewController class]];
MJSettingItem *product = [MJSettingArrowItem itemWithIcon:@"MoreNetease" title:@"产品推荐" destVcClass:[MJTest1ViewController class]];
MJSettingItem *about = [MJSettingArrowItem itemWithIcon:@"MoreAbout" title:@"关于" destVcClass:[MJTest1ViewController class]]; MJSettingGroup *group = [[MJSettingGroup alloc] init];
group.items = @[update, help, share, viewMsg, product, about];
[self.data addObject:group];
} /**
* 第0组数据
*/
- (void)setupGroup0
{
MJSettingItem *pushNotice = [MJSettingArrowItem itemWithIcon:@"MorePush" title:@"推送和提醒" destVcClass:[MJTest1ViewController class]];
MJSettingItem *handShake = [MJSettingSwitchItem itemWithIcon:@"handShake" title:@"摇一摇机选"];
MJSettingItem *soundEffect = [MJSettingSwitchItem itemWithIcon:@"sound_Effect" title:@"声音效果"]; MJSettingGroup *group = [[MJSettingGroup alloc] init];
group.items = @[pushNotice, handShake, soundEffect];
[self.data addObject:group];
} - (void)viewDidLoad
{
[super viewDidLoad]; // 1.标题
self.title = @"设置"; // 2.添加数据
[self setupGroup0];
[self setupGroup1];
}
@end

效果如下:

系统源码下载:点击下载

iOS 网易彩票-4设置模块一的更多相关文章

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

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

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

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

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

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

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

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

  5. iOS 网易彩票-2框架搭建-代码重构

    在上一篇中,我们基本已经把整个框架都搭建出来了,下面进行代码重构一下. 思路: 导航按钮,按下时,会变灰,那是系统自带了,通过自定义UIButton,实现按下按钮立即切换效果. MJTabBarCon ...

  6. iOS菜鸟成长笔记(2)——网易彩票练习

    距离上一篇<第一个iOS应用>已经有一个多月了,今天来和大家一起学习和分享一下一个小练习<网易彩票> 首先我们向storyboard中拖入一个TabBarController和 ...

  7. iOS开发——实战总结OC篇&网易彩票开发知识点总结

    网易彩票开发知识点总结 关于网易彩票开发中遇到了不少的坑,弄了好久才弄懂,或者有些犹豫很久没用就不记得了,所以这里就总结了一下,希望以后不会忘记,就算忘记也能快速查看! /************** ...

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

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

  9. UI进阶之--网易彩票手写plist文件,动态创建控制器与tableViewcell

    点击右上角设置按钮 点击按钮后发生的事件:1. 控制器的跳转,进入新的控制器.view, 2. 跳转的时候对将要跳转的目标控制的子控件进行了布局.---通过手写plist文件的方式加载 为按钮注册单击 ...

随机推荐

  1. JS - 二叉树算法实现与遍历 (更新中...)

    一.关于二叉树: 截图来自:https://segmentfault.com/a/1190000000740261 温馨提示:学习以及使用二叉树概念,心中永远有这么一个图,对于理解和接受二叉树有很大的 ...

  2. G711算法学习

    采样和量化 首先需要明确的两个概念,“采样”和“量化”.对于给定的一个波形,采样是从时间上将连续变成离散的过程,而采样得到的值,可能还是不能够用给定的位宽(比如8bit)来表示,这就需要经过量化,即从 ...

  3. sencha touch 百度地图扩展(2014-6-24)(废弃 仅参考)

    扩展代码如下: Ext.define('ux.BMap', { alternateClassName: 'bMap', extend: 'Ext.Container', xtype: 'bMap', ...

  4. linux 终端输出颜色

    在Linux终端下调试程序时,有时需要输出大量信息.若能控制字体的颜色和显示方式,可使输出信息对比鲜明,便于调试时观察数据. 终端的字符颜色由转义序列(Escape Sequence)控制,是文本模式 ...

  5. CF 166E Tetrahedron

    E. Tetrahedron time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  6. HDU 1455 Sticks(经典剪枝)

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  7. 熟悉使用ConfigParser库读写配置文件

    Python的配置文件 配置文件 setting.ini文件是一个纯文本 [DataBase1] username = admin passwors = root [DataBase2] hostna ...

  8. 获取Web.config的内容

    <web.config> web.config文件是一个XML文件,它的根结点是<configuration>,在<configuration>节点下的常见子节点有 ...

  9. html to openxml

    Html to OpenXml How to start ? Create a new console application. Add a reference to DocumentFormat.O ...

  10. jenkins中windows节点设置开机自启动slave-agent

    做web UI自动化时,为了提高效率,用了多台windows节点来跑自动化,但slave-agent每次在关机后都得手工启动,麻烦,网上看到了一系列说启动任务中,感觉还是不考虑,这里使用windows ...