首页 > 代码库 > 我彩票自己的笔记

我彩票自己的笔记

 

<style></style>

彩票-设置核心功能

 

(彩票项目的精髓:引导页的循环利用思想,在一个就是这个设置页面—>调转table封装利用)

4.1我的彩票—>设置—>重点来了核心功能()之前页面的跳转用的是拖线,接下来用代码实现跳转。

     点击设置按钮push一个TableViewController控制器

     Setting(设置)功能放到一起;报的错误?:duplicate symbols for architecture //又重复定义的类;

     push控制器,隐藏底部导航条:vc.hidesBottomBarWhenPushed = YES;

     [self.navigationController pushViewController : vc animated:YES];很多控制器push出来的导航条要隐藏:重写push方法

     修改系统的API方法添加功能,重写导航控制器的方法

     来到这个,导航条用的是自己定义的导航条,重写:

??-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{

          //通过导航控制的子控制器的数来判断到底是不是根控制器self.viewControllers.count==0//等于0说明第一个添进去的时候根控制器,

// push之前判断一下是不是根控制器

     if(self.viewControllers.count !=0){

          viewController.hidesBottomBarWhenPushed = YES;

          }

[super push…];

  }

非根控制器的底部导航条都要隐藏,

复习一下:给导航控制器设置根控制器的时候,root的时候底层都会调用pushViewController:animated 这个方法;

     [导航控制器 initWithRootViewController : vc];

 

     统一设置导航返回按钮(导航控制器的左边的按钮)

     什么时候需要设置:也是非根控制器的时候才需要设置返回按钮。

     获取UIBarButtonItem setBackButtonTitlePositionAdjustment:UIOffsetMake。。。一般不使用这个方法;(setback,leftbar

     只有栈顶控制器才能设置导航控制器的左边的按钮(栈顶控制器即是要push的控制器的)

第一种方法:定义左边按钮设置图片

     if(self.viewControllers.count !=0){

          viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@“”] style:UIBarButtonItemStyleBordered target : self action:@selector(back)];

          //重写了left按钮,点击事件也要自己实现一下下;

     }

     -(void)back{

          [self popViewControllerAnimated:YES];//self就是导航控制器;( 栈存储先进后出)

     }

第二种设置左边按钮的方式:(本身有剪头图片修改原本的颜色,去掉文字)

     [bar setTintColor:[UIColor whiteColor]];

     [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0,-100) forBarMetrics:UIBarMetricsDefault];

**系统自带的返回按钮,有滑动返回功能—>自定义按钮会把这个功能给抹杀掉;

     自定义按钮也想要滑动返回功能???

      self.interactivePopGestureRecognizer.delegate = nil; //还原滑动返回功能;(返回手势代理清空了怎么触发监听方法等呢);

     这里有一个BUG:手势交互的代理清空了,其他的手势也监听不到了

     清空滑动代理之前先保存一份,在返回之后在复原之前清空的代理;(在哪里保存在哪里复原呢?)

     //保存—>搞一个强引用的成员变量

     self.popDelegate = self.interactivePopGestureRecognizer.delegate;

 

     //复原的时候也要注意是否是根控制器,不是根控制器不需要还原(点—>—>—>)

??-(UIViewController *)popViewControllerAnimated :(BOOL)animated{

//popView之后判断这个count 是1 那就是只剩下一个根控制器了;

if(self.viewControllers.count ==1 ){

self.interactivePopGestureRecognizer.delegate = self.popDelegate;//复原

}

          //在这里写有一个BUG滑一半的时候,马上就还原了,——>又没有了滑动功能

[super …];

}

 

那要等这个pop动画完全还原的时候,再去还原—>监听这个动画什么时候完成

设置导航控制器的代理—>自己来监听

遵守代理:<UINavigationControllerDelegate>

代理的方法:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{

//代理的这个方法不管是push,还是pop方法展示控制控制器,只要是完全展示完都会调用;

//viewController参数就是当前展示完的控制器;

if(viewController == [self.viewControllers firstObject]){//当前这个控制器是不是控制器数组里的第一个(根控制器)

self.interactivePopGestureRecognizer.delegate = self.popDelegate;//复原

}

}

如果展示的是根控制器,就还原pop手势代理;

push 是进入下一个控制器,栈顶压入控制器;pop是退回到上一个控制器取出了栈顶控制器

 

 

4.2深入了解系统的手势滑动功能(添加一个手势,实现手势对应的方法)

//系统的self.popDelegate = self.interactivePopGestureRecognizer.delegate;代理做个一个滑动功能,而且做了一系列的判断;(根控制器就不能滑动)

自定义返回滑动功能(添加手势,实现手势方法—>系统的基础上修改)

 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:系统的target对象 action:@selector(系统的滑方法)];

怎么拿到系统的target对象???

 

??重点:

self.interactivePopGestureRecognizer//系统的一个滑动手势,系统也是使用Target(对象)实现了滑动功能action(方法)

/*

<UIScreenEdgePanGestureRecognizer: 0x10033e1b0; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x100411740>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x10033d320>)>>

 

系统滑动手势类型:UIScreenEdgePanGestureRecognizer

target:_UINavigationInteractiveTransition

action:handleNavigationTransition:

 

*/

??// 防止手势冲突self.interactivePopGestureRecognizer.enabled = NO;

取出系统的target对象

取出某个对象的属性—>获取系统的私有属性;—->通过运行时遍历一个对象的属性;

1.KVC—>前提条件:必须知道属性名

??运行时框架:<objc/runtime.h>

遍历某个类里面的所有属性:

class_copyIvarList(__unsafe_unretained Class cls ,unsigned int *outCount);

这方法会返回一个成员属性的数组 Ivar *ivars = 指向数组第一个元素地址的

//Class 获取哪个类的成员属性(当前类,不包括父类)

//count:告诉你当前类里面成员属性的总数(传的是一个地址)&count

Ivar *ivars = class_copyIvarList([UIGestureRecognizer class],&count);

接下里遍历这个数组:

for(int i = 0; i < count; i ++){//遍历出所有属性名

Ivar ivar = ivars[i];//取出每一项刚刚遍历返回的数组

NSString *ivarName = @(ivar_getName(ivar)) //

ivar_getName();//获取属性名;

ivar_getTypeEncoding(Ivar v);//获取属性的类型;

ivar_getOffset(Ivar v);//偏移量吧;

//将C语言字符串转化成OC字符串; @()

NSLog(@“%@”,ivarName);//打印的是私有属性_targets

}

_targets:属性名 对应的属性值value———>KVC

??以上一推都是为了获得(知道)这个_targets这个属性名

知道了这个属性名之后呢,可以通过KVC获得某对象的_targets属性值

NSArray targets = [self.interactivePopGestureRecognizer valueForKeyPath:@“_targets”];

self.interactivePopGestureRecognizer是一个手势对象,拥有UIGestureRecognizer对象的属性;

NSArray  targets 是一个数组:(action = handleNavigationTransition; target = <UINavigationInteractiveTransition>

取出数组里的元素看看是啥

id objc = [targets firstObject];//取出数组的第一个元素,是一个对象;

用断点看看objc有什么属性:_target,_action;

取出target对象:id target = [objc valueForKeyPath:@“_target”];

结果:自己创建的手势调用系统target对象,实现系统的handleNavigationTransition:方法;

自己写的有个BUG,系统的有个delegeate做了一些事情,当是根控制的时候,这手势会造成各种事件失灵;

所以,自己充当代理,实现代理的一个方法:当是根控制器的时候,手势不可用:

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{

//当前控制器就是栈顶控制器;

return (self.topViewController != [self.viewControllers firstObject]);

}

 

一种简单的方式获得target:

self.interactivePopGestureRecognizer.delegate就是上面获得target对象;

 

——————自定义滑动功能完—————————

 

4.3搭建设置的table页面(MVC思想去管理这个TableViewController

每一个cell要展示的内容不同 ——>XMGSettingItem : NSObject

image ,title, subtitle

+(instancetype)itemWithImage:(UIImage *)image title:(NSString *)title

{

XMGSettingItem *item =[ [self alloc] init];

item.image = image;

item.title = title;

return item;

}

 

XMGSettingGroup模型

items,headTitle,footTitle;

+(instancetype) groupWithItems:(NSArray *items){

    XMGSettingGroup *group = [[self alloc] init];

    group.items = items;

    return group;

}

 

组模型中有个数组的成员属性是用来存放每个cell内容的的items模型;

细化cell—>item模型,对于带尖头的(要跳转),switch(是YES是NO):

给每一个 cell设置一个模型;模型分类:(剪头,switch)

搞个继承XMGSettingItem的模型XMGArrowSettingItem,XMGSwitchSettingItem

XMGArrowSettingItem,创建模型的时候,剪头就用这个

 

 

XMGSwitchSettingItem:创建模型的时候Switch就用这个

@property(nonatomic, assign) BOOL isOn;

 

设置cell内容的时候判断是哪种模型 [item isKindOfClass : [XMGArrowSettingItem class]];

cell模型既然有多种,又要重复利用—>cell复原操作;

 

cell封装: XMGSettingCell

@class XMGSettingItem;

+(instancetype)cellWithTableView:(UITableView *)tableView;

@property (nonatomic, strong) XMGSettingItem *item;//把这个模型传进来好给cell赋值;

 

@property (nonatomic ,strong) UIImageView *arrowView;//不能和系统的重名

@property (nonatomic ,strong) UISwitch *switchView;

-(UIImageView *)arrowView{//懒加载

if(_arrowView == nil){  

_arrowView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@“”]];

}

return _arrowView;

}

-(UISwitch *)switchView{//懒加载

if(_switchView ==nil){

_switchView = [[UISwitch alloc] init];

}

return _switchView;

}

+(instancetype)cellWithTableView:(UITableView *)tableView{

static NSString *ID = @“cell”;

XMGSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

if(cell == nil){

cell = [[XMGSettingCell alloc] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier:ID];

}

return cell;

}

-(void)setItem:(XMGSettingItem *)item

{

_item = item;

[self setUpData];

[self setUpAccessoryView];

}

 

//给cell设置数据

-(void)setUpData{

self.textLabel.text = _item.title;

self.detailTextLabel.text = _item.subTitle;

self.imageView.image = _item.image;

}

//给cell设置辅助视图

-(void)setUpAccessoryView{

if([_item isKindOfClass:[XMGArrowSettingItem class]]){

self.accessoryView = self.arrowView;

self.selectionStyle = UITableViewCellSelectionStyleDefault;

}else if([_item isKindOfClass:[XMGSwitchSettingItem class]]){

self.accessoryView = self.switch;

//switch不要行选中样式;

self.selectionStyle = UITableViewCellSelectionStyleNone;

}else{

self.selectionStyle = UITableViewCellSelectionStyleDefault;//还原

self.accessoryView = nil;//还原;

}

}

 

 

4.4 App版本检测— >用到了服务请求—>高斯模糊地图提示功能

高斯模糊的实现原理:截屏—>生成图片—>对图片进行处理(第三方框架DRNRealTimeBlurView)

用第三方框架:封装起来用(搞自己的一个view继承这个框架)

XMGBlurView :DRNRealTimeBlurView

//DRNRealTimeBlurView他会把父控件截屏,做高斯模糊效果;

当cell点击的时候-(void)tableView: didSelectRowAtIndexPath:{

//判断组判断行;

XMGBlurView *blurView = [XMGBlurView alloc] initWithFrame:XMGScreenBounds];

[XMGKeyWindow addSubview : blurView];

 

[MBProgressHUD showSuccess:@“”];

dispatch_after(dispatch_time),dispatch_get_main_queue(),^{

[blurView removeformSuperView];

}

//点击事件,功能写在这里很恶心??,而且每一个cell都有自己的功能且还可以保存到模型中,最好写在block

}

??在模型中定义block,保存代码快:void没有返回值,^block标志,itemOperation是block变量名,后面的()是有米有参数; 

给cell模型(父类)添加属性:@property (nonatomic , strong) void(^ itemOperation )();

 

取消按钮的选中:[tableView deselectRowAtIndexPath : indexPath animated : YES];

itemOperation = ^{

//block代码写在这快

}

 

点击cell跳转,在block中添加代码,所有的剪头cell都要跳转就会写很多重复的代码—>不好

来到跳转的模型XMGArrowSettingItem,添加descVc属性外界只要告诉要转转的控制器就可以了,XMGArrowSettingItem帮你跳descVc

//保存一个需要跳转的控制器

@property (nonatomic, weak) Class descVc; //用Class有提示,以免类名写错,Class不是对象,不用带*

 

if(item.itemOperation){

item.itemOperation();

return;//如果有block的话,就会有跳转操作;如果没有block,那么接着往下判断有米有传个类名进来,进行跳转;

}

if( [item isKindOfClass : [XMGArrowSettingItem class]] ){//判断下是不是掉转的类,在判断有米有传destVc

if(arrowItem.destVc){

UIViewController *vc = [UIViewController alloc] ]init];

[self.navigationController pushViewController :vc animated:YES];

}

}

 

补充:cell选中与否-(void)setUpAccessoryView{

//在这个方法中设置要不要选中功能;还记得得还原;

}

 

4.5点击推送———>跳转到和tableView很像的界面;

我彩票自己的笔记