iOS笔记056 - UI总结02

九宫格布局

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

?

时间: 2024-02-20 07:59:12

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

iOS笔记055 - UI总结

1.程序启动后的开始动画 程序启动后可以加载一个简单的动画界面来介绍程序或者用户信息. 可以使用一个xib来描述界面.并且如果想在程序加载完成后第一个加载这个xib文件,需要在Appdelegate中手动加载这个xib // 通过stroyboard启动,跟控制器的view并不会在程序启动完成的时候添加到窗口,属于懒加载范畴 // 程序启动完成的时候调用 - (BOOL)application:(UIApplication *)application didFinishLaunchingWith

李洪强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 类,通过 EMClient 类可以获取到 chatManager.groupManager.contactManager.roomManager对象.原来 2.0 版本的 SDK 很多方法提供了同步.异步回调.异步(block)三种方法,3.0 版只提供同步方法(async开头的方法为异步方法). 例如: //2.0

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

iOS开发Swift篇(02) NSThread线程相关简单说明 一 说明 1)关于多线程部分的理论知识和OC实现,在之前的博文中已经写明,所以这里不再说明. 2)该文仅仅简单讲解NSThread在swift语境中的一些使用和注意点,别他. 3)本文涉及代码可以从https://github.com/HanGangAndHanMeimei/Code地址获得. 二 NSThread的基本使用和创建 1)基本用法(主线程|当前线程) 1 //1.获得执行该方法的当前线程 2 let currentT

iOS instruments之ui automation的简单使用(高手绕道)

最近使用了几次instruments中的automation工具,现记录下automation的简单使用方法,希望对没接触过自动化测试又有需求的人有所帮助.  UI 自动测试是iOS 中重要的附加功能,它由名为"Automation"的新的工具对象支持.Automation工具的脚本是用JavaScript语言编写,主要用于分析应用的性能和用户行为,模仿/击发被请求的事件,利用它可以完成对被测应用的简单的UI测试及相关功能测试. 一. 简单的录制脚本 打开xcode,这里用我为我家亲爱

iOS之微博UI实例--拟物化设计(未彻底成功)

*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute

iOS笔记:Objective-C自定义NSLog宏

/*  XCode LLVM XXX - Preprocessing中Debug会添加 DEBUG=1 标志  */ #ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORM

学习ios笔记第一天的C语言学习记录

c语言基础学习 int num1 = 15; int num2 = 5; int temp = 0; //先把num1放到temp里 temp = num1; //先把num2放到num1里 num1 = num2; //先把temp放到num2里 num2 = temp; 算数运算符 +加法运算 -减法运算符 *乘法运算符 /除法运算符  ------整型相除取整,除数不为0 %取余运算符 ------两边均为整数 ++递增运算-------运算符在前,先执行:运算符在后,后执行: --递减运

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

小伙伴们,苹果终于在今天凌晨推送了 iOS 8 的正式版.虽然该系统并未与 iPhone6 发布会同时亮相,但对于已经提前体验尝鲜过测试版的同学来说并不陌生.iOS 8 几乎每个图标都进行了重新设计,即使是不那么显眼的后退按钮.这里就给大家分享最新的 iOS 8 矢量 UI 素材套件,可以免费下载使用. 立即去下载      素材主页 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12个让人惊叹的的创意的 404 错误页

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

李洪强iOS开发之-环信02.2_环信官网下载环信 SDK 移动客服即时通讯云 iOS SDK 当前版本:V3.1.4 2016-07-08 [ 版本历史 ] | 开发指南 | 知识库 | Demo源码 | 最新SDK下载Demo扫码安装 切换至v2.x版本 iOS SDK v2.x 当前版本:V2.2.6 2016-06-28 [ 版本历史 ] | 开发指南 | 知识库 | Demo源码 | 最新SDK下载Demo扫码安装 返回v3.x版本 Android SDK 当前版本:V3.1.4 20