标签:
UICollectionViewController
创建控制器一定要指定默认的布局样式。
// 加载一个九宫格布局的控制器,必须指定布局样式
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout?alloc] init];
vc = [[SLQGuideCollectionController?alloc] initWithCollectionViewLayout:layout];
也可以重写控制器的init方法
- (instancetype)init
{
? ? UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout?alloc] init];
? ? // 初始化必须指定默认的布局样式
? ? return [super?initWithCollectionViewLayout:layout];
}
在指定布局时可以设置各种属性
- (instancetype)init
{
? ? UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout?alloc] init];
? ? // cell大小
? ? layout.itemSize = SLQScreenBounds.size;
? ? // 水平间距
//? ? layout.minimumInteritemSpacing = 0;
? ? // 垂直间距
? ? layout.minimumLineSpacing = 0;
? ? // 每一组距离四面的距离
//? ? layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
? ? // 滚动方向
? ? layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
?? ?
? ? // 初始化必须指定默认的布局样式
? ? return [super?initWithCollectionViewLayout:layout];
}
如果想显示控件,那么使用方法和UITableView非常相似。使用代理设置每个CollectionView
// 一共多少组
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
? ? return 1;
?? ?
}
// 某组多少元素
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
? ? return? 4;
}
// cell 的内容
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
? ? // 只能以这种方式创建cell,首先注册xib或者类,然后去缓存池中取,如果缓存池没有就自己创建一个新的cell
? ? SLQGuideCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:IDforIndexPath:indexPath];
? ? // 设置cell内容
? ? NSString *imageName = [NSString stringWithFormat:@"guide%ldBackground",indexPath.item + 1];
? ? cell.image = [UIImage imageNamed:imageName];
? ? return cell;
}
首先包含头文件,然后使用里面的方法即可
// 运行时对象
#import <objc/runtime.h>
?
? ??// 遍历某个类里面所有属性 Ivar:表示成员属性
? ? // copyIvarList只能获取哪个类下面的属性,并不会越界(不会把它的父类的属性给遍历出来)
? ? // Class 获取哪个类的成员属性
? ? // count:告诉你当前类里面成员属性的总数
? ? //? ? unsigned int count = 0;
? ? //? ? // 返回成员属性的数组
? ? //
? ? int count = 0;
? ? Ivar *name = ? class_copyIvarList([UIGestureRecognizer class], &count);
? ? for (int i = 0; i < count; i ++) {
? ? ? ? Ivar ivar = name[i];
? ? ? ? // 获取属性名
? ? ? ? NSString *proName = @(ivar_getName(ivar));
?? ? ? ? NSLog(@"%@",proName);
? ? }
?
//<UIScreenEdgePanGestureRecognizer: 0x7fb6ba46f1c0; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fb6ba7481b0>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fb6ba46d8e0>)>>
//UIScreenEdgePanGestureRecognizer:手势类型
//target - _UINavigationInteractiveTransition
//action - handleNavigationTransition
可以看到系统默认在滑动手势时作的一些事情,指定了手势的target和action,可以利用这些方法来自定义自己的手势。
1、首先要找到这个手势相关联的属性和方法。因为是私有的,不能直接看到,所以只能通过运行时机制获取属性名
先通过运行时机制的一些函数,观察属性名,然后确定在自己要得。
int count = 0;
Ivar *name = ? class_copyIvarList([UIGestureRecognizer class], &count);
for (int i = 0; i < count; i ++) {
? ? Ivar ivar = name[i];
? ? // 获取属性名
? ? NSString *proName = @(ivar_getName(ivar));
?? ? NSLog(@"%@",proName);
}
2、找出属性名并添加手势
// 找到属性名
NSArray *arr = [self.interactivePopGestureRecognizer?valueForKey:@“_targets"];
// 获取属性
id objc = [arr firstObject]; //? -(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7f7f93f5adf0>)
// 获取方法target
id target = [objc valueForKey:@"_target"]; //
// 添加自定义手势,指定方法位系统内部私有的方法handleNavigationTransition:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer?alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate?action:@selector(handleNavigationTransition:)];
pan.delegate = self;
[self.view?addGestureRecognizer:pan];
3、实现代理方法-只要不是根控制器就使用手势
// UIGestureRecognizerDelegate 代理方法
// 是否开始手势,如果是不是根控制器就开始手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
? ? ? // 判断下当前控制器是否是跟控制器
? ? return (self.topViewController != [self.viewControllersfirstObject]);
}
?
这个方法是别人封装好的,直接拿来使用即可。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
? ? if (indexPath.section == 2 && indexPath.row == 0) {
?? ? ? ? // 弹出窗口,指定frame
? ? ? ? SLQSettingBlurView *blur = [[SLQSettingBlurView?alloc] initWithFrame:SLQScreenBounds];
? ? ? ? [SLQKeyWindow addSubview:blur];
? ? ? ? // 弹出提示窗口
? ? ? ? [MBProgressHUD showSuccess:@"没有最新版本"];
? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
? ? ? ? ? ? // 隐藏高斯窗口
? ? ? ? ? ? [blur removeFromSuperview];
? ? ? ? });
? ? }
}
?
? ? // block会把代码里所有强指针全部强引用
? ? // 解决循环利用的问题
?? ?
? ? //? ? __weak XMGScoreViewController *weakSelf = self;
?? ?
? ? // typeof获取括号里面的类型
? ? __weak typeof(self) weakSelf = self;
?? ?
? ? // 在iOS7之后只要在cell上添加textField都自动做了键盘处理
? ? item.itemUpdate = ^(NSIndexPath *indexPath)
? ? {
?? ? ? ?
? ? ? ? // 获取当前选中的cell
? ? ? ? UITableViewCell *cell = [weakSelf.tableView cellForRowAtIndexPath:indexPath];
?? ? ? ?
? ? ? ? // 弹出键盘
? ? ? ? UITextField *textField = [[UITextField alloc] init];
?? ? ? ?
? ? ? ? [textField becomeFirstResponder];
?? ? ? ?
? ? ? ? [cell addSubview:textField];
?? ? ? ?
? ? };
? ??
文件中保存的时字典数据
[
? {
? ? "title" : "如何领奖?",
? ? "html" : "help.html",
? ? "id" : "howtoprize"
? },
? {
? ? "title" : "如何充值?",
? ? "html" : "help.html",
? ? "id" : "howtorecharge"
? },
]
?直接当做普通文件读取就行
- (NSMutableArray *)items
{
? ? if (_items == nil) {
? ? ? ? _items = [NSMutableArray array];
? ? ? ? NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"help.json" ofType:nil];
?
? ? ? ? NSData *data = [NSData dataWithContentsOfFile:fullPath];
? ? ? ? // 从文件读取数据
? ? ? ? NSDictionary *allData = [NSJSONSerialization?JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
? ? ? ? for (NSDictionary *dict in allData) {
? ? ? ? ? ? SLQHtmlItem *item = [SLQHtmlItem itemWithDict:dict];
? ? ? ? ? ? [_items addObject:item];
? ? ? ? }
//? ? ? ? NSLog(@"%@",allData);
?? ? ? ?
? ? }
//? ? NSLog(@"%@",_items);
? ? return _items;
}
?关键一句话是使用?NSJSONSerialization?对文件进行解析
??NSDictionary?*allData = [NSJSONSerialization?JSONObjectWithData:data?options:NSJSONReadingAllowFragments error:nil];
那么读取时就要进行修正,使用KVC进行字典读取要保证,模型中得属性和字典中元素数量和名称一致,不能有任何差别。
现在的问题就是,文件中又一项数据的key是id,这个和系统的保留字id冲突,必须对id进行转换。所以声明属性是大写ID。
@property (strong, nonatomic) NSString *ID;
?然后是初始化方法,使用 KVC进行读取
+ (instancetype)itemWithDict:(NSDictionary *)dict
{
? ? SLQHtmlItem *item = [[self alloc] init];
? ? // KVC,会出问题,id 和 ID无法自动转换
? ? [item? setValuesForKeysWithDictionary:dict];
? ? // 使用通用方法更加方便,抽出分类
//? ? SLQHtmlItem *item? = [SLQHtmlItem objectWithDict:dict mapDict:@{@"ID":@"id"}];
?? ?
? ? return item;
}
?
重写setvalue方法,在方法里进行转换,这个可以应对数量较少的键值对冲突,如果有十几个或者更多,使用起来就很麻烦,要写一堆if语句。
?
// 因json文件中得字典key 是id,与系统关键字冲突,手动判断再返回正确的值
- (void)setValue:(id)value forKey:(NSString *)key
{
? ? // 判断是不是id
? ? if ( [key isEqualToString:@"id"]) {
?? ? ? ?
? ? ? ? [self setValue:value forKey:@"ID"];
?? ? ? ?
? ? }
? ? else
? ? {
? ? ? ? [super setValue:value forKey:key];
? ? }
}
更加方便的方法是抽出一个 分类,因对更加复杂的情况,如果有10个key和系统关键字重复,这个分类比较好使。
// 快速进行字典转模型
// mapDict:模型中的哪个属性名跟字典里面的key对应
+ (instancetype)objectWithDict:(NSDictionary *)dict mapDict:(NSDictionary *)mapDict
{
? ? id obj = [[self alloc] init];
? ? // 运行时遍历模型中得属性
? ? unsigned int count = 0;
? ? Ivar *ivar = class_copyIvarList(self, &count);
? ? for (int i = 0 ; i < count ; i ++) {
? ? ? ? // 取出
? ? ? ? Ivar var = ivar[i];
? ? ? ? // 取出模型
? ? ? ? NSString *name = @(ivar_getName(var));
? ? ? ? // s输入如下,有一个_,直接去掉就可得到属性名
? ? ? ? // 菜皮[61496:622121] _title
? ? ? ? // 菜皮[61496:622121] _html
? ? ? ? // 菜皮[61496:622121] _ID
? ? ? ? // 去除下划线
? ? ? ? name = [name substringFromIndex:1];
?? ? ? ?
? ? ? ? id value = dict[name];
?? ? ? ?
? ? ? ? // 需要由外界通知内部,模型中属性名对应字典里面的哪个key
? ? ? ? // ID -> id
? ? ? ? if (value == nil) {
? ? ? ? ? ? //
? ? ? ? ? ? if(mapDict)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 获取真实的key
? ? ? ? ? ? ? ? NSString *key = mapDict[name];
? ? ? ? ? ? ? ? value = dict[key];
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? [obj setValue:value forKey:name];
?? ? ? ?
//? ? ? ? NSLog(@"%@",name);
? ? }
? ? return obj;
}
?
使用方法,要初入一个冲突的字典
SLQHtmlItem *item? = [SLQHtmlItem objectWithDict:dict mapDict:@{@"ID":@"id"}];
?
标签:
原文地址:http://www.cnblogs.com/songliquan/p/4623479.html