一 initialize方法
+ (void)initialize
- 第一次使用这个类或者它的子类的时候调用,但是并不是说只会调用一次。
- 初始化子类的时候,先初始化父类,在初始化子类
+ (void)load
- 如果一个类只想做一次操作的时候,在load方法里去调用
二 新特性界面加立即体验
- 最后一个 cell 加上立即体验
- 封装方法最后一个 cell 判断方法 XMGNewFeatureCell
// 用来判断下当前cell对象是否是最后一个cell
- (void)setIndexPath:(NSIndexPath *)indexPath count:(int)count
{
if (indexPath.item == count - 1) {
// 最后一个cell
// 添加一个立即体验按钮,首先保存整个cell只有一个体验按钮
// 显示这个按钮
self.startBtn.hidden = NO;
}else{ // 不是最后一个cell
// 隐藏这个按钮
self.startBtn.hidden = YES;
}
}
- 懒加载,保证一个控件只有一个
- (UIButton *)startBtn
{
if (_startBtn == nil) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
_startBtn= btn;
[btn setBackgroundImage:[UIImage imageNamed:@"guideStart"] forState:UIControlStateNormal];
[btn sizeToFit];
// 监听点击
[btn addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside];
btn.center = CGPointMake(self.width * 0.5 , self.height * 0.9);
[self.contentView addSubview:btn];
}
return _startBtn;
}
// 点击立即体验按钮的时候调用
- (void)start
{
// 跳转到主框架界面。界面之间跳转,导航控制器,tabBarVc,modal
// 不能使用modal原因:新特性界面一直存在,被窗口的根控制器一直强引用
XMGTabBarController *vc = [[XMGTabBarController alloc] init];
// 设置窗口的根控制器为主框架控制器
XMGKeyWindow.rootViewController = vc;
}
- 封装一个工具类,专门用来存储XMGSaveTool
// 读取数据
+ (id)objectForKey:(NSString *)defaultName
{
return [[NSUserDefaults standardUserDefaults] objectForKey:defaultName];
}
// 存储数据
+ (void)setObject:(id)value forKey:(NSString *)defaultName
{
[[NSUserDefaults standardUserDefaults] setObject:value forKey:defaultName];
}
- 选择根控制器XMGRootTool
- 抽取AppDelegate里的的判断版本代码
+ (UIViewController *)chooseWindowRootVC
{
// 判断下当前有没有最新的版本
// 最新的版本保存到info.plist文件
NSString *curVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];
// 获取上一次保存的最新版本号
NSString *lastVersion = [XMGSaveTool objectForKey:"version"];
UIViewController *rootVc;
if ([curVersion isEqualToString:lastVersion]) { // 相等
// 没新版本,进入主框架界面
// 创建tabBarVc
rootVc = [[XMGTabBarController alloc] init];
}else{ // 表示有最新的版本号,进入新特性界面
// 如果有,进入新特性界面
rootVc = [[XMGNewFeatureViewController alloc] init];
// 保存当前的最新的版本号
[XMGSaveTool setObject:curVersion forKey:"version"];
// 新特性界面:就是展示几张图片
}
return rootVc;
}
三 搭建设置界面
- 非根控制器隐藏 tabBar 条
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.childViewControllers.count != 0) { // 非跟控制器
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
- 设置 tableview 样式,重写XMGSettingViewController的 init 方法
- (instancetype)init
{
return [self initWithStyle:UITableViewStyleGrouped];
}
- 建一模型XMGSettingItem,模型决定 cell 展示
@interface XMGSettingItem : NSObject
/** 描述cell图片 */
@property (nonatomic, strong) UIImage *image;
/** 描述cell文字 */
@property (nonatomic, strong) NSString *title;
+ (instancetype)itemWithImage:(UIImage *)image title:(NSString *)title;
@end
+ (instancetype)itemWithImage:(UIImage *)image title:(NSString *)title
{
XMGSettingItem *item = [[self alloc] init];
item.image = image;
item.title = title;
return item;
}
- 数组模型XMGGroupItem
+ (instancetype)groupWithItems:(NSArray *)items
{
XMGGroupItem *group = [[self alloc] init];
group.items = items;
return group;
}
- 第一组样式
// 添加第0组
- (void)setUpGroup0
{
// 创建行模型
// 使用兑换码
XMGSettingItem *RedeemCode = [XMGSettingItem itemWithImage:[UIImage imageNamed:@"RedeemCode"] title:@"使用兑换码"];
// Items:存储当前数组有多少行模型
// 创建一个组模型,描述第0组
XMGGroupItem *group = [XMGGroupItem groupWithItems:@[RedeemCode]];
// 设置头部标题
group.headerTitle = @"abc";
// 添加组模型到groups数组,有多少个组模型就有多少组
[self.groups addObject:group];
}
- cell 设置 数据源
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.groups.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// 取出当前的组模型
XMGGroupItem * group = self.groups[section];
return group.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
// 取模型
// 哪一组的模型
XMGGroupItem *group = self.groups[indexPath.section];
// 从模型数组数组中取出对应的模型
XMGSettingItem *item = group.items[indexPath.row];
cell.imageView.image = item.image;
cell.textLabel.text = item.title;
return cell;
}
// 返回第section组的头部标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// 取出当前是哪一组
XMGGroupItem *group = self.groups[section];
return group.headerTitle;
}
// 设置第section组的尾部标题
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
// 取出当前是哪一组
XMGGroupItem *group = self.groups[section];
return group.footerTitle;
}
四 设置 cell 完善
根据行模型确定cell右边辅助视图
- 1.提供一个类型枚举,箭头,开头
- 2.用子类去判断cell的类型(这个方法更加面向对象)
- 箭头类 XMGSettingArrowItem
- 开关类 XMGSettingSwitchItem
- @property (nonatomic, assign) BOOL isOpen;
封装 cell 创建方法
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"cell";
XMGSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[XMGSettingCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
return cell;
}
- 封装cell 模型
- (void)setItem:(XMGSettingItem *)item
{
_item = item;
// 设置子控件数据
[self setUpData];
// 设置辅助视图
[self setUpAccessoryView];
}
#pragma mark - 设置辅助视图
- (void)setUpData
{
self.imageView.image = _item.image;
self.textLabel.text = _item.title;
}
#pragma mark - 设置辅助视图
- (void)setUpAccessoryView
{
// 设置辅助视图
if ([_item isKindOfClass:[XMGSettingArrowItem class]]) {
// 展示箭头
UIImageView *arrowView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow_right"]];
self.accessoryView = arrowView;
}else if ([_item isKindOfClass:[XMGSettingSwitchItem class]]){
// 展示开关
UISwitch *switchView = [[UISwitch alloc] init];
self.accessoryView = switchView;
}else{
self.accessoryView = nil;
}
实现点击 cell 跳转对应 view
- 保存一个跳转的控制器类名
- 1.字符串 (有可能会写错)
- 2.Class
- 目的控制器的类名 Class:一般用assign
@property (nonatomic, assign) Class descVc;
- 保存一个跳转的控制器类名
保存控制器
// 设置目的控制器的类名
push.descVc = [XMGPushViewController class];
- descVc有值需要跳转
if (arrowItem.descVc) {
// 创建目的控制器
UIViewController *vc = [[arrowItem.descVc alloc] init];
vc.navigationItem.title = item.title;
// 跳转界面
[self.navigationController pushViewController:vc animated:YES];
}
- 设置导航栏标题
- (void)viewDidLoad {
[super viewDidLoad];
// self.navigationItem.title = @"设置";
// 另一种简单写法
self.title = @"设置";
}
- 检查新版本 cell 完善
- 第三方框架MBProgressHUD
- 经常用到会增加很多判断语句,封装一个 block,方便调用
- XMGSettingItem.h
/** 保存点击cell做的事情 */
@property (nonatomic, strong) void(^operationBlock)();
// 保存检查新版本需要做的事情
version.operationBlock = ^{
[MBProgressHUD showSuccess:@"没有最新的版本"];
};
- 监听 cell 点击代码段
// 判断下有木有事情,就判断下block有没有值
if (item.operationBlock) {
// 执行保存的代码
item.operationBlock();
return;
}
- block 使用注意点:
- 避免循环引用
- block 会把代码块里面所有的强指针强引用
- 在 block 中最好不要直接访问成员属性
- 弱指针.成员属性:weakSelf.groups
- 解决循环引用,weak
- 把 self 强指针转换为弱指针
__weak XMGSettingViewController *weakSelf = self
- 另一种写法:typeof(x)获取 x 的类型XMGSettingViewController
__weak typeof(self) *weakSelf = self
- 把 self 强指针转换为弱指针
五 设置推送界面
- 抽取基类
- XMGPushViewController
// 添加第0组
- (void)setUpGroup0
{
// 创建行模型
// 开奖推送
XMGSettingArrowItem *item = [XMGSettingArrowItem itemWithImage:nil title:@"开奖推送"];
item.descVc = [UIViewController class];
// 比分直播
XMGSettingArrowItem *item1 = [XMGSettingArrowItem itemWithImage:nil title:@"比分直播"];
item1.descVc = [XMGScoreViewController class];
// 中奖动画
XMGSettingArrowItem *item2 = [XMGSettingArrowItem itemWithImage:nil title:@"中奖动画"];
// 购彩提醒
XMGSettingArrowItem *item3 = [XMGSettingArrowItem itemWithImage:nil title:@"购彩提醒"];
// Items:存储当前数组有多少行模型
// 创建一个组模型,描述第0组
XMGGroupItem *group = [XMGGroupItem groupWithItems:@[item,item1,item2,item3]];
// 添加组模型到groups数组,有多少个组模型就有多少组
[self.groups addObject:group];
}
- 推荐关注比赛 XMGScoreViewController
- 创建3组cell(都封装好了)
- (void)setUpGroup0
{
// 创建行模型
XMGSettingSwitchItem *item = [XMGSettingSwitchItem itemWithImage:nil title:@"关注比赛"];
// 创建组模型
XMGGroupItem *group = [XMGGroupItem groupWithItems:@[item]];
group.footerTitle = @"sadsad";
// 添加groups数组
[self.groups addObject:group];
}
- (void)setUpGroup1
{
// 创建行模型
XMGSettingItem *item = [XMGSettingItem itemWithImage:nil title:@"起始时间"];
item.subTitle = @"00:00";
// 创建组模型
XMGGroupItem *group = [XMGGroupItem groupWithItems:@[item]];
// 添加groups数组
[self.groups addObject:group];
}
- (void)setUpGroup2
{
// 创建行模型
XMGSettingItem *item = [XMGSettingItem itemWithImage:nil title:@"结束时间"];
item.subTitle = @"23:59";
__weak typeof(self) weakSelf = self;
item.operationBlock = ^(NSIndexPath *indexPath){
// 获取选中的cell,把键盘添加到cell上面
UITableViewCell *cell = [weakSelf.tableView cellForRowAtIndexPath:indexPath];
// 弹出键盘
UITextField *textField = [[UITextField alloc] init];
[textField becomeFirstResponder];
[cell addSubview:textField];
// 在iOS7之后,只要把textField添加到需要弹出键盘的cell上面,就会自动做好键盘处理
};
// 创建组模型
XMGGroupItem *group = [XMGGroupItem groupWithItems:@[item]];
// 添加groups数组
[self.groups addObject:group];
}
- 拖动view退出键盘
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self.view endEditing:YES];
}