九宫格布局

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. nodejs一个函数实现消息队列中间件

    消息队列中间件(Message Queue)相信大家不会陌生,如Kafka.RabbitMQ.RocketMQ等,已经非常成熟,在大大小小的公司和项目中也已经广泛使用. 有些项目中,如果是只使用初步的 ...

  2. 【JavaScript 封装库】Prototype 原型版发布!

    /* 源码作者: 石不易(Louis Shi) 联系方式: http://www.shibuyi.net =============================================== ...

  3. cocosBuilder生成cbbi文件,绑定到cocos2d-x

      cocosBuilder生成cbbi文件,绑定到cocos2d-x 分类: Cocos2D-X2013-04-27 20:37 4651人阅读 评论(6) 收藏 举报 今天弄了一天.记录一下. 首 ...

  4. [Python]面向对象近期笔记-super

    Python面向对象高级 直接调用父类方法 class A: def __init__(self): print("hello") class B(A): def __init__ ...

  5. centos7 kvm安装使用

    kvm简介 KVM 全称是 Kernel-Based Virtual Machine.也就是说 KVM 是基于 Linux 内核实现的. KVM有一个内核模块叫 kvm.ko,只用于管理虚拟 CPU ...

  6. 创建自己的网站博客--Hexo

    原文地址:https://www.xingkongbj.com/blog/hexo/creat-hexo.html 安装环境 安装 node 下载对应版本并安装 node . 安装 Git Windo ...

  7. Maven_项目管理工具

    Maven 一.Maven是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目的 二.Maven的好处: 0.节省空间:对jar包做了统一管理 依赖管理,项目里无需放jar包 ...

  8. Nagios 监控Windows服务器(详细篇)

    1. 监控内容 windows服务器的内部参数包括以下 a. 内存使用状况 b. CPU负载 c. 磁盘使用状况 d. 服务状态 e. 运行的进程 2. 监控原理 在windows服务器内安装NSCl ...

  9. 3.4.2 Undefined类型【JavaScript高级程序设计第三版】

    Undefined 类型只有一个值,即特殊的 undefined.在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined,例如: var message; alert(me ...

  10. C语言基础篇(一)关键字

    导航: 1. 数据类型 !!! 2. 自定义类型 !!!! 3. 逻辑结构 4. 类型修饰符 !! 5. 杂项 !! ----->x<------------->x<----- ...