九宫格布局

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;

}

 运行时 - runtime

首先包含头文件,然后使用里面的方法即可

// 运行时对象

#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 循环利用

    // 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];

        

    };

    

 json文件

文件中保存的时字典数据

[

  {

    "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"}];

 

iOS笔记056 - UI总结02的更多相关文章

  1. iOS笔记057 - UI总结03

    控制器的父子关系 1.控制器父子关系的建立原则        如果2个控制器的view是父子关系(不管是直接还是间接的父子关系),那么这2个控制器也应该为父子关系 [self.view addSubv ...

  2. iOS笔记055 - UI总结01

      1.程序启动后的开始动画 程序启动后可以加载一个简单的动画界面来介绍程序或者用户信息. 可以使用一个xib来描述界面.并且如果想在程序加载完成后第一个加载这个xib文件,需要在Appdelegat ...

  3. iOS开发Swift篇(02) NSThread线程相关简单说明

    iOS开发Swift篇(02) NSThread线程相关简单说明 一 说明 1)关于多线程部分的理论知识和OC实现,在之前的博文中已经写明,所以这里不再说明. 2)该文仅仅简单讲解NSThread在s ...

  4. 李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档

    李洪强iOS开发之-环信02.1_环信 SDK 2.x到3.0升级文档 SDK 2.x 至 3.0 升级指南 环信 SDK 3.0 升级文档 3.0 中的核心类为 EMClient 类,通过 EMCl ...

  5. 荼菜的iOS笔记--UIView的几个Block动画

    前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...

  6. 免费素材下载:iOS 8 矢量 UI 素材套件

    小伙伴们,苹果终于在今天凌晨推送了 iOS 8 的正式版.虽然该系统并未与 iPhone6 发布会同时亮相,但对于已经提前体验尝鲜过测试版的同学来说并不陌生.iOS 8 几乎每个图标都进行了重新设计, ...

  7. iOS之微博UI实例--拟物化设计(成功了90%)

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  8. 李洪强iOS开发之-环信02.2_环信官网下载环信 SDK

    李洪强iOS开发之-环信02.2_环信官网下载环信 SDK 移动客服即时通讯云 iOS SDK 当前版本:V3.1.4 2016-07-08 [ 版本历史 ] | 开发指南 | 知识库 | Demo源 ...

  9. IOS开发-UI学习-sqlite数据库的操作

    IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这 ...

随机推荐

  1. 基数排序C#界面版

    第一步:生成数据  第二步:读取数据 第三步:创建队列 第四步:入队分配 第五步:出队收集重复第四步与第五步,直到出队入队各四次,完成基数排序:如下:4次入队结束后如下:最后一次出队:基数排序完成.. ...

  2. MYSQL 之SET GLOBAL innodb_buffer_pool_size =n

    工作遇到一个情况是索引相同的情况下,mysql服务在linux上运行很快,在windows服务器上运行很慢,版本是V5.7以后得版本,同事查找了下说应该设置 SET GLOBAL innodb_buf ...

  3. 【BZOJ4555】[TJOI2016&HEOI2016] 求和(NTT)

    点此看题面 大致题意: 计算\(\sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*(j!)\),其中\(S\)为第二类斯特林数. 推式子 首先让我们来推一波式子: 因为当\(i&l ...

  4. [pytorch] Pytorch入门

    Pytorch入门 简单容易上手,感觉比keras好理解多了,和mxnet很像(似乎mxnet有点借鉴pytorch),记一记. 直接从例子开始学,基础知识咱已经看了很多论文了... import t ...

  5. kubernetes-控制器statefulset和Job(十三)

       从前面的学习我们知道使用Deployment创建的pod是无状态的,当挂载了Volume之后,如果该pod挂了,Replication Controller会再启动一个pod来保证可用性,但是由 ...

  6. 谷歌浏览器兼容IE插件

    谷歌浏览器兼容IE插件 http://pan.baidu.com/s/1i31hspf

  7. 一篇RxJava友好的文章(二)

    上一篇文章介绍了rxjava的基本用法,和一些常用的操作符,以及rxjava的链式操作带来的好处.由于rxjava非常的强大,让我如此的痴迷,我打算写五篇文章,专门讲解rxjava 常见的操作符和用法 ...

  8. textkit

    更详细的内容可以参考官方文档 <Text Programming Guide for iOS>. “Text Kit指的是UIKit框架中用于提供高质量排版服务的一些类和协议,它让程序能够 ...

  9. 注释java中某个方法过时

    添加一个注解即可 @Deprecated

  10. python中正则表达式在中文字符串匹配时的坑

    之前一直有使用python 正则表达式来做中文字符串或者中英文数字混合的字符串的匹配,发现有不少情况下会匹配失灵或者结果混乱,并且在不同操作系统上匹配结果也不一致,查了很久都不知道是什么原因.今天终于 ...