1.UINavigationController
//导航控制器, 用于去管理多个视图控制器的切换
//管理的模式: 栈(先进后出)
//创建导航控制器
UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:rootVC];
self.window.rootViewController = naVC;
[rootVC release];
//每一个NavigationController都自带一个navigationBar
//UINavigationBar, 导航栏, 继承于UIView
//修改导航栏的颜色
naVC.navigationBar.barTintColor = [UIColor greenColor];
//修改导航栏的样式, 会影响状态栏的颜色; Default, 状态栏字为黑色, Black, 状态栏字为白色
naVC.navigationBar.barStyle = UIBarStyleBlack;
//渲染颜色, 对图像和文字进行处理
naVC.navigationBar.tintColor = [UIColor greenColor];
//是否半透明
naVC.navigationBar.translucent = YES;
2.UINavigationItem
//继承于NSObject, 每一个viewController都自带有一个navigationItem, 主要负责显示 文字 和 按钮
//标题
self.navigationItem.title = @"主页";
//自定义标题
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
titleLabel.text = @"首页";
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.font = [UIFont systemFontOfSize:40];
self.navigationItem.titleView = titleLabel;
[titleLabel release];
//提示(一般用不到)
//self.navigationItem.prompt = @"这是主页";
//UIBarButtonItem, 按钮
继承于UIBarItem
//参数1: 样式
//参数2: 目标
//参数3: 方法名
//左侧按钮
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(helloWorld)];
self.navigationItem.leftBarButtonItem = leftItem;
[leftItem release];
//右侧按钮
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(helloWorld)];
self.navigationItem.rightBarButtonItem = rightItem;
[rightItem release];
//导航控制器, 入栈的视图控制器集合
NSLog(@"%@", self.navigationController.viewControllers);
//当前可见的视图控制器
NSLog(@"%@", self.navigationController.visibleViewController);
//栈顶的视图控制器
NSLog(@"%@", self.navigationController.topViewController);
1.UITableView
//表视图, 继承于UIScrollView
//用于去展示一系列具有相同数据结构的内容
//不像word中的表格, 只能够展示一列内容
//创建TableView, 指定大小和样式
//样式
//1.UITableViewStylePlain, 常规表格
//2.UITableViewStyleGrouped, 组合表格
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
tableView.delegate = self;
//属性
//样式, 只读属性, 只能在初始化的时候进行设定
NSLog(@"%ld", tableView.style);
//行高, 默认高度44
tableView.rowHeight = 60;
//分隔线样式
//1.None, 没有分隔线
//2.SingleLine, 单行分割线(默认值)
//3.SingleLineEtched, 单行虚线分隔线
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
//分隔线颜色
tableView.separatorColor = [UIColor redColor];
//分隔线间距, 只能够修改左右间距
//UIEdgeInsets, 结构体, 成员变量上上左下右, 多用于设置四周边距
tableView.separatorInset = UIEdgeInsetsMake(0, 20, 0, 20);
//背景颜色
tableView.backgroundColor = [UIColor yellowColor];
//背景视图
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"桔梗.jpg"]];
imageView.frame = self.view.frame;
tableView.backgroundView = imageView;
//设置是否允许多选
tableView.allowsMultipleSelection = YES;
//创建UIImage
//1.通过名字找图片
//UIImage *nameImage = [UIImage imageNamed:@"桔梗.jpg"];
//2.通过路径找图片
//NSBundle, 包类
//[NSBundle mainBundle], 找到主包. 就是找到*.app, 所有的资源都放在*.app中
//NSString *path = [[NSBundle mainBundle] pathForResource:@"桔梗" ofType:@"jpg"];
//UIImage *pathImage = [UIImage imageWithContentsOfFile:path];
//表头
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 375, 30)];
headerLabel.text = @"iOS应用排行榜";
headerLabel.textColor = [UIColor greenColor];
headerLabel.textAlignment = NSTextAlignmentCenter;
tableView.tableHeaderView = headerLabel;
[headerLabel release];
//表尾
UILabel *footLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 375, 30)];
footLabel.text = @"此处省略几千款应用";
footLabel.textAlignment = NSTextAlignmentCenter;
footLabel.textColor = [UIColor greenColor];
tableView.tableFooterView = footLabel;
[footLabel release];
//设置多余分隔线, 使它们不显示
tableView.tableFooterView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
//tableView, 想要显示数据, 使用dataSource模式, dataSource实质是代理
//步骤
//1.成为tableView的数据源
//2.实现协议中的两个必须完成的方法
tableView.dataSource = self;
#pragma mark - UITableViewDataSource
//某个分区有多少行(必须完成的方法)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//只有一个分区, 或者 每个分区行数相等
return 5;
//多个分区, 并且行数不一致
// if (section == 0) {
// return 3;
// } else {
// return 4;
// }
}
//显示的单元格(必须完成的方法)
//会执行多次, 每走一次, 创建一个cell; 第一次, 只创建出一个屏幕能够显示的cell, 如果滚动tableView, 会再走这个方法, 再次创建cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//UITableViewCell, 单元格类, 继承于UIView, 用于在UITableView上显示内容
//参数1, 样式
//Default, 默认样式, imageView, textLabel
//Value1, 值1, imageView, detailTextLabel
//Value2, 值2, textLabel, detailTextLabel
//Subtitle, 子标题, imageView, textLabel, detailTextLabel
//cell的重用机制(复用机制), 用于降低内存消耗
//1.定义重用标识符
static NSString *cellIdentifier = @"CELL";
//2.先从复用池找cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//3.判断是否能够找到cell
if (cell == nil) {
NSLog(@"+++");
//没有找到cell, 创建cell
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
//辅助标识符
//Clickmark, 对号
//DetailButton, 圆圈里有个i
//DisclosureButton = DetailButton + DisclosureIndicator
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
//4.设置cell显示的内容
cell.textLabel.text = [NSString stringWithFormat:@"分区:%ld, 行数:%ld", indexPath.section, indexPath.row];//NSIndexPath, 在这里用于存储cell的位置(第几分区和第几行)
//cell.contentView, 是textLabel, detaiTextLabel和imageView的父视图
return cell;
}
//分区个数, 默认是1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
//区头标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *array = @[@"A", @"B", @"C"];
return array[section];
}
//区尾标题
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
NSArray *array = @[@"AAA", @"BBB", @"CCC"];
return array[section];
}
//索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return @[@"A", @"B", @"C"];
}
#pragma mark - UITableViewDelegate
//cell高度, 为每个cell设置高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 60;
} else {
return 30;
}
}
//区头设置
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 1) {
return 100;
} else {
return 50;
}
}
//区尾高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 60;
}
//自定义区头视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 44)];
headerView.backgroundColor = [UIColor greenColor];
return [headerView autorelease];
}
//自定义区尾视图
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 50)];
footerView.backgroundColor = [UIColor yellowColor];
return [footerView autorelease];
}
//点击某个cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"点击了第%ld个分区的第%ld个cell", indexPath.section, indexPath.row);
}
//取消点击
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"取消了");
}
1.UITableEdit
//1.让tableView进入编辑状态
- (void)startEdit:(UIBarButtonItem *)item {
if (flag) {
item.title = @"编辑";
} else {
item.title = @"完成";
}
flag = !flag;
//进入编辑状态的两个方法
//[tableView setEditing:YES];//不带动画
[catTableView setEditing:flag animated:YES];//带动画
}
//2.指定哪些行可以进行编辑(dataSource中的方法)
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return NO;
}
return YES;
}
//3.设置进入编辑状态的样式(delegate中的方法)
// 默认删除
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == self.catArray.count - 1) {
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}
//4.编辑完成(dataSource中的方法)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%ld", editingStyle);
//editingStyle用于区分是添加操作还是删除操作
if (editingStyle == UITableViewCellEditingStyleDelete) {
//先删除数据(数据先行)
[self.catArray removeObjectAtIndex:indexPath.row];
//tableView删除某些行
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
if (editingStyle == UITableViewCellEditingStyleInsert) {
//添加数据
[self.catArray addObject:@"helloKitty"];
//tableView添加某些行
NSIndexPath *addIndexPath = [NSIndexPath indexPathForRow:self.catArray.count - 1 inSection:indexPath.section];
[tableView insertRowsAtIndexPaths:@[addIndexPath] withRowAnimation:UITableViewRowAnimationTop];
}
}
2.移动
//1.让tableView进入编辑状态(同上)
//2.指定哪些行可以移动(dataSource中的方法)
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
//2.移动完成(dataSource中的方法)
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
NSLog(@"从第%ld行移动到第%ld行", sourceIndexPath.row + 1, destinationIndexPath.row + 1);
//(1)保留原来的数据
NSString *tempString = [[self.catArray objectAtIndex:sourceIndexPath.row] retain];//一定要retain保留一份
//(2)删除旧位置上的数据
[self.catArray removeObjectAtIndex:sourceIndexPath.row];
//(3)在新的位置上插入数据
[self.catArray insertObject:tempString atIndex:destinationIndexPath.row];
[tempString release];
for (NSString *tempString in self.catArray) {
NSLog(@"%@", tempString);
}
}
//UITabBarController, 标签视图控制器, 用于管理多个平级的视图控制器, 继承于UIViewController
UITabBarController *tabBarC = [[UITabBarController alloc] init];
//UITabBar, UITabBarController自带的标签栏, 多个视图控制器共用一个, 继承于UIView, 控制样式
//访问tabBar
//tabBarC.tabBar
//样式
tabBarC.tabBar.barStyle = UIBarStyleBlack;
//设置标签栏的颜色
tabBarC.tabBar.barTintColor = [UIColor yellowColor];
//文字和图片的渲染颜色
tabBarC.tabBar.tintColor = [UIColor redColor];
//半透明
tabBarC.tabBar.translucent = NO;
//UITabBarItem, 主要用于控制文字和按钮的显示, 继承于UIBarItem, 每一个视图控制器都自带有一个tabBarItem
//通过数组的形式, 去管理平级的视图控制器
FirstViewController *firstVC = [[FirstViewController alloc] init];
//由于tabBarController的控制机制, 所以设置viewController的tabBarItem统一在外部设置
firstVC.tabBarItem.title = @"First";
SecondViewController *secondVC = [[SecondViewController alloc] init];
secondVC.tabBarItem.title = @"Second";
ThirdViewController *thirdVC = [[ThirdViewController alloc] init];
thirdVC.tabBarItem.title = @"Third";
FourthViewController *fourthVC = [[FourthViewController alloc] init];
fourthVC.tabBarItem.title = @"fourth";
tabBarC.viewControllers = @[firstVC, secondVC, thirdVC, fourthVC];
[firstVC release];
[secondVC release];
[thirdVC release];
[fourthVC release];
self.window.rootViewController = tabBarC;
[tabBarC release];
navigationController和tabBarController所管理控制的视图控制器运行机制的区别
//navigationController所管理控制的视图控制器的运行机制
//1.显示的第一个页面是rootViewController
//2.push到下一个页面的执行流程
//a.init
//b.入栈
//c.viewDidLoad(正常情况, 只执行一次)
//d.viewWillAppear
//e.viewDidAppear
//3.pop回上一个页面的执行流程
//a.viewWillDisappear
//b.viewDidDisappear
//tabBarController所管理控制的视图控制器运行机制
//1.显示的第一个页面viewControllers中的第一个视图控制器
//2.切换视图的执行流程
//a.第一个视图控制器, 执行viewDidLoad
//b.其他的视图控制器, 当切换时, 才执行viewDidLoad
//c.如果已经执行过viewDidLoad的视图控制器, 再次切换, 不再执行viewDidLoad
//三大视图控制器
//UIViewController
//UINavigationController
//UITabBarController
//1.UITabBarController和UINavigationController 都继承于UIViewController
//2.UIViewController, 侧重展示内容;
//3.UINavigationController和UITabBarController, 侧重管理视图控制器
//4.UINavigationController, 管理的视图控制器是层层递进
//5.UITabController, 管理的视图控制器是平级的
1.HTTP协议
(1)网络参考模型
//每一层都有相关的协议, 协议制定了规范
//A. OSI(open system interconnection, 开放式网络互联), 分7层. 由ISO(国际标准化组织)制定
//1.应用层
//2.表示层
//3.会话层
//4.传输层
//5.网络层
//6.数据链路层
//7.物理层
//B. TCP/IP, 美国国防部制定, 分4层
//1.应用层(123) FTP, HTTP
//2.传输层(4) TCP, UDP
//3.网络层(5) IP
//4.物理层(67) WiFi, 以太网
(2)HTTP: 一种协议, 超文本传输协议
//客户端/服务器
//建立连接(三次握手)
//1.客户端发送请求
//2.服务器收到请求, 并告知客户端
//3.客户端收到服务器的确定信息, 建立连接成功
//断开连接(四次挥手)
//1.客户端发送断开请求给服务器
//2.服务器收到客户端的请求, 并告知客户端, 此时客户端断开连接
//3.服务器发送断开请求给客户端
//4.客户端收到服务器的请求, 并告知服务器, 此时服务器断开连接
2.iOS平台如何实现HTTP请求
//(1)一些需要用到的概念
//⺴络请求地址对象NSURL
//⺴络请求对象NSURLRequest、NSMutableURLRequest
//⺴络链接对象NSURLConnection
//⺴络链接协议NSURLConnectionDelegate
//⺴络请求数据信息NSURLResponse
//url,统一资源定位符,也被称为网址,因特网上标准的资源网址
//1.根据数据存放的位置, 分为GET请求和POST请求
//2.根据是否需要等待, 分别同步请求和异地请求
//(2)GET和POST的区别
//1.GET请求的参数, 放在url的后面, 以?开头, 参数是key-value出现, 多个参数用&连接
//POST请求的参数, 仿造httpBody里, 以NSData形式存在
//2.GET通过网址字符串给服务器传输数据
//POST通过data
//3.GET传输数据最多255字节
//POST容量超过1G
//4.GET所有传输给服务器的数据, 都显示在网址内, 类似明文密码, 直接可见
//POST数据则被转换为NSData, 无法直接读取
//(3)同步和异步的区别
//同步请求获取的数据, 方法的返回值NSData, 容易造成程序卡死
//异步请求获取的数据, 在delegate方法中 或者 block中
//(4)网络请求的流程
//1.urlString, 如果字符串中有中文, 需要转码
//2.url
//3.urlRequest, GET请求用NSURLRequest, POST请求用NSMutableURLRequest, 因为POST需要修改HTTPMethod和HTTPBody
//4.urlConnection, 同步请求方法只有一个, 异步请求可以选择delegate或block, delegate模式要实现的方法
//a.请求失败, 有error
//b.收到服务器的响应NSURLResponse
//c.收到数据, 数据是分包返回的
//d.请求完成, 此时数据是完整的, 可以对其进行转码, 进而对其解析
//5.解析, XML和JSON, XML解析分了两种方式SAX和DOM解析, JSON相对比较简单
//使用GET和POST请求由后台服务器人员 规定, 在接口文档中有说明
//同步和异步请求由 开发人员自己 决定,一般建议使用异步, 防止出现假死状态
//在真实的开发中, 会对网络请求进行封装
1.UICollectionView和UITableView设计思想的区别
//(1)UITableView的布局样式由tableView和delegate
//UICollectionView的布局样式由UICollectionViewFlowlayout和UICollectionDelegateFlowLayout
//(2)UITableView的数据由UITableViewDataSource控制
//UICollectionView的数据由UICollectionViewDataSource控制
//(3)UITableView是一个单列多行表视图
//UICollection是一个多行多列集合视图
//(4)UITableView上显示的是UITableViewCell
//UICollectionView上显示的是UICollectionViewCell
//(5)UITableViewCell自带contentView, imageView, textLabel, detailTextLabel
//UICollectionViewCell自带contentView
//(6)UITableViewCell, 创建时使用复用机制, 如果cell没找到需要自己创建
//UICollectionCell, 创建时使用"复用 + 注册"机制, 如果cell没有找到, 系统自动创建cell
//(7)UITableView自带编辑(添加, 删除) 和 移除功能
//UICollectionView没有编辑功能
2.UICollectionView
//集合视图, 继承于UIScrollView, 实现和UITableView很一致
//UICollectionViewLayout, 控制集合视图的布局类, 继承于NSObject
//UICollectionViewLayout, 是抽象基类, 不能够直接使用, 要通过子类化的形式才能够使用, 系统为我们提供了一个子类UICollectionViewFlowLayout;
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//滚动方向
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
//cell大小
layout.itemSize = CGSizeMake(50, 50);
//最小行间距
layout.minimumLineSpacing = 20;
//item之间的最小距离
layout.minimumInteritemSpacing = 20;
//区头大小
layout.headerReferenceSize = CGSizeMake(375, 50);
//区尾大小
layout.footerReferenceSize = CGSizeMake(375, 50);
//设置分区间距, 不包含区头和区尾, 只影响内容部分的间距
layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
//要显示数据 需要设置dataSource
collectionView.dataSource = self;
//设置delegate
collectionView.delegate = self;
//向复用池中注册cell类型和对应的标识符, 方便系统发现复用池中没有cell的话, 会根据你提供的cell类型和标识符, 创建出一个cell
//注册cell
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
//注册区头
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier];
//注册区尾
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerIdentifier];
//背景颜色
collectionView.backgroundColor = [UIColor grayColor];
//背景视图
//collectionView.backgroundView
//是否允许多选
collectionView.allowsSelection = YES;
//数据发生了变化, 需要重载数据
[collectionView reloadData];
[self.view addSubview:collectionView];
3.dataSource和delegate方法
#pragma mark - UICollectionViewDataSource
//某个分区的cell(item)个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 30;
}
//返回cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
;
//UICollectionViewCell, 继承于UICollectionReusableView, cell上没有空间, 如果需要空间, 需要自定义cell
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor yellowColor];
return cell;
}
//分区个数
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 3;
}
//设置区头和区尾
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
//collectionView的区头和区尾也使用的复用机制;
//参数1: 区分是区头还是区尾
//参数2: 注册的标识符
//参数3: 所在的位置
//根据kind类型判断是区头还是区尾
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier forIndexPath:indexPath];
headerView.backgroundColor = [UIColor greenColor];
return headerView;
}
else {
UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerIdentifier forIndexPath:indexPath];
footerView.backgroundColor = [UIColor cyanColor];
return footerView;
}
}
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"点击了%ld, %ld", indexPath.row, indexPath.section);
DetailViewController *detailVC = [[DetailViewController alloc] init];
[self.navigationController pushViewController:detailVC animated:YES];
}
#pragma mark - UICollectionViewDelegateFlowLayout
//返回某个cell的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0:
return CGSizeMake(30, 30);
break;
case 1:
return CGSizeMake(20, 20);
break;
default:
return CGSizeZero;
break;
}
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(10, 10, 10, 10);
}
//返回某个分区的最小行间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout {
return 10;
}
//返回某个分区, item的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 10;
}
//返回某个分区的区头大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return CGSizeMake(100, 100);
}
//返回某个分区的区尾大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
return CGSizeMake(50, 50);
}
分享:
0

喜欢
0

赠金笔
1.数据持久化
//数据持久化: 数据永久的保存
//数据持久化的实质: 把数据写入文件, 再把文件存到硬盘(沙盒)
//我们存储在内存中的数据, 只是临时的, 当程序关闭时, 它们便会被释放, 使得数据丢失, 这无疑是非常糟糕的事情, 因此, 便有了数据持久化, 即将数据通过文件的形式存储到程序的沙盒中
2.沙盒机制
//iOS沙盒机制: iOS系统为每个App生成一个文件夹(沙盒), 这个文件夹只允许当前的APP访问
//所谓沙盒, 其实本质便是一个文件夹, 它的主目录名字是由 十六进制 和 - 组成, 来保证沙盒安全性
//在沙盒之中, 有Documents, Library, tmp三部分组成
(1)Documents
//文件, 存放一些比较重要的用户信息, 比如游戏存档
//Documents中的文件会被备份 或者 存入iCloud中, 所以存入到Documents中的文件不能过大, 如果过大, 会在应用审核过程中遭到拒审
//参数1: 文件名称
//参数2: 搜索域, 优先级user>local>network>system
//参数3: 相对路径或者绝对路径, YES是绝对, NO是相对
//因为相同文件名的文件可能有多个, 所以返回的是一个数组
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
(2)Library
//资源库, 存一些不太重要, 相对比较大的文件, 有2个子文件夹
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"%@", libraryPath);
//1.Caches, 缓存, 网页缓存, 图片缓存, 应用中的"清理缓存"功能, 就是清理的这个文件夹下的内容
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"%@", cachesPath);
//LanchImages, 由LaunchScreen.xib生成的启动图片
//2.Preferences, 偏好设置, 存用户对这个应用的设置或配置
//注: 路径找不到, 通过NSUserDefaults访问
//3.tmp, 临时文件, 存放下载的压缩包
NSString *tempPath = NSTemporaryDirectory();
NSLog(@"%@", tempPath);
3.简单对象(NSString, NSData, NSArray, NSDictionary)的文件读写
(1)NSString的文件读写
NSString *string = @"想回到过去";
//指定文件路径
//Documents路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//指定文件路径 aaa.txt
NSString *filePath = [docPath stringByAppendingPathComponent:@"aaa.txt"];
NSLog(@"%@", filePath);
//写入文件
//参数1: 文件路径, 如果文件路径下没有此文件, 系统会自动创建一个文件
//参数2: 是否使用辅助文件
//参数3: 编码格式
//参数4: 错误
NSError *error = nil;
BOOL result = [string writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (result) {
NSLog(@"写入成功");
} else {
NSLog(@"写入失败:%@", error);
}
//取值操作
NSError *error1 = nil;
NSString *contentString = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error1];
if (error1) {
NSLog(@"出现错误error:%@", error1);
} else {
NSLog(@"文件内容%@", contentString);
}
[contentString release];
(2)NSArray的文件读写
NSArray *array = @[@"123", @"abc", @"apm"];
//写入操作, 格式:xml
//Library, test.txt
//Library路径
NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
//文件路径
NSString *filePath = [libPath stringByAppendingPathComponent:@"test.txt"];
//写入
BOOL result = [array writeToFile:filePath atomically:YES];
//判断是否写入成功
if (result) {
NSLog(@"写入成功");
} else {
NSLog(@"莫名其妙");
}
//取值操作
NSArray *contentArray = [[NSArray alloc] initWithContentsOfFile:filePath];
NSLog(@"%@", contentArray);
[contentArray release];
(3)NSDictionary的读写操作, 格式: xml
NSDictionary *dic = @{@"a": @"aaa", @"1": @"111", @"*": @"***"};
//Caches, dic.txt
//写入操作
//Caches文件路径
NSString *dicPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
//dic.txt路径
NSString *filePath = [dicPath stringByAppendingPathComponent:@"dic.txt"];
//写入
BOOL result = [dic writeToFile:filePath atomically:YES];
//判断写入是否成功
if (result) {
NSLog(@"写入成功");
} else {
NSLog(@"写入失败");
}
//取值操作
NSDictionary *contentDic = [[NSDictionary alloc] initWithContentsOfFile:filePath];
NSLog(@"%@", contentDic);
[contentDic release];
(4)NSData的读写操作
NSString *string = @"123456789";
//字符串转data
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
//tmp, data.txt
//tmp路径
NSString *dataPath = NSTemporaryDirectory();
//data.txt路径
NSString *filePath = [dataPath stringByAppendingPathComponent:@"data.txt"];
//写入
BOOL result = [data writeToFile:filePath atomically:YES];
//判断是否写入成功
if (result) {
NSLog(@"写入成功");
} else {
NSLog(@"写入失败");
}
//取值
NSData *contentData = [[NSData alloc] initWithContentsOfFile:filePath];
NSString *contentSting = [[NSString alloc] initWithData:contentData encoding:NSUTF8StringEncoding];
NSLog(@"%@", contentSting);
[contentData release];
4.复杂对象的读写(归档 / 反归档)
//归档的实质: 把其他类型的数据(Person), 先转化为NSData, 再写入文件
//能进行归档的对象必须遵守
//归档
Person *person = [[Person alloc] initWithName:@"女票" age:@"18" gender:@"女"];
NSLog(@"%@", person);
//可变Data
NSMutableData *mData = [[NSMutableData alloc] initWithCapacity:0];
//NSKeyedArchiver, 压缩工具, 继承于NSCoder, 主要用于编码
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mData];
//把Person对象压到Data中
[archiver encodeObject:person forKey:@"girlFriend"];
//完成压缩
[archiver finishEncoding];
[archiver release];
NSLog(@"%@", mData);
//主目录, person.txt
NSString *personPath = NSHomeDirectory();
//路径
NSString *filePath5 = [personPath stringByAppendingPathComponent:@"person.txt"];
//写入
BOOL result = [mData writeToFile:filePath5 atomically:YES];
//判断是否写入成功
if (result) {
NSLog(@"写入成功");
} else {
NSLog(@"写入失败");
}
[mData release];
//反归档
NSMutableData *contentData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
//NSKeyedUnarchiver, 解压工具, 继承于NSCoder
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:contentData];
//寻找到person对象并解压
Person *contentPerson = [unarchiver decodeObjectForKey:@"girlFriend"];
NSLog(@"%@", contentPerson);
[unarchiver release];
5.NSFileManager
//文件管理工具, 主要用于添加, 移动, 修改, 拷贝文件, 继承于NSObject
//文件管理工具是个单例
NSFileManager *fm = [NSFileManager defaultManager];
//文件路径
NSString *dPath = [[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
NSLog(@"%@", dPath);
//创建文件夹
//主目录, Images
NSString *mainPath = NSHomeDirectory();
NSString *directoryPath = [mainPath stringByAppendingPathComponent:@"Images"];
NSLog(@"%@", directoryPath);
NSError *error = nil;
// NSDictionary *attributes = @{NSFileAppendOnly: @YES};
BOOL result1 = [fm createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:&error];
if (result1) {
NSLog(@"创建成功");
} else {
NSLog(@"出现错误:%@", error);
}
//创建文件
//images, image.png
NSString *imagePath = [directoryPath stringByAppendingPathComponent:@"image.png"];
NSLog(@"%@", imagePath);
NSString *girlPath = [[NSBundle mainBundle] pathForResource:@"赵灵儿" ofType:@"jpg"];
NSData *imageData = [NSData dataWithContentsOfFile:girlPath];
result1 = [fm createFileAtPath:imagePath contents:imageData attributes:nil];
if (result1) {
NSLog(@"创建成功");
} else {
NSLog(@"创建失败");
}
//判断文件是否存在
if ([fm fileExistsAtPath:imagePath]) {
NSLog(@"存在");
//删除
NSError *error = nil;
[fm removeItemAtPath:imagePath error:&error];
if (result1) {
NSLog(@"删除成功");
} else {
NSLog(@"删除失败:%@", error);
}
}
1.多线程
//进程: 获取一个程序能够运行的资源(比如: 内存)
//线程: 最小的执行单元, 分配和调度资源
//一个进程, 必须有一个线程
//只有一个线程的, 称单线程, 这个线程叫主线程
//程序就相当于一个餐馆, 餐馆需要资源(房子, 桌子等)由进程负责采集和购买; 线程相当于服务员, 负责分配资源
//一个服务员(主线程)
//两个服务员(主线程和子线程), 例如, 假如我要同时实现太极转动的动画 和 打印招待客人的数量 这两件事情, 那么, 就需要两个线程才可以
//主线程: 转太极
//子线程: 招待客人
//主线程和子线程的区别
//1.主线程占1M内存, 子线程占512内存
//2.子线程不能够给释放内存, 必须手动释放内存, 添加自动释放池
//3.子线程内不能够更新UI(会失败), 必须在主线程中更新UI
2.NSObject, 后台异步执行, 自动创建一个后台线程
[self performSelectorInBackground:@selector(food) withObject:nil];
3.NSThread
//线程类, 继承NSObject
//获取主线程
NSThread *mainThread = [NSThread mainThread];
NSLog(@"%@", mainThread);
//获取当前线程
NSThread *currentThread = [NSThread currentThread];
NSLog(@"%@", currentThread);
//线程名字
NSLog(@"%@", mainThread.name);
//创建一个线程
NSThread *serverThread = [[NSThread alloc] initWithTarget:self selector:@selector(food) object:nil];
serverThread.name = @"餐馆";
//开启线程
[serverThread start];
[serverThread release];
//线程休眠sleep
[NSThread sleepForTimeInterval:0.3];
//线程取消cancel
[serverThread cancel];
//判断是不是主线程
if ([serverThread isMainThread]) {
NSLog(@"是主线程");
} else {
NSLog(@"不是主线程");
}
4.NSOperationQueue
//操作队列, 继承NSObject, 自动生成线程, 操作队列中存放的元素是NSOperation
//NSOperation, 操作类, 抽象基类, 只能执行一次
//1.NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(food) object:nil];
//2.block
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
[self food];
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//最大并发数, 默认值: NSOperationQueueDefaultMaxConcurrentOperationCount
queue.maxConcurrentOperationCount = 1;
[queue addOperation:invocation];
//[queue addOperation:block];
[invocation release];
5.GCD
//大中央调度, Grand Central Dispatch
//三种队列
(1)主调队列, 主线程
dispatch_queue_t mainQueue = dispatch_get_main_queue();
NSLog(@"%@", mainQueue);
(2)全局队列, 绑定子线程
//参数1: 队列优先级
//DISPATCH_QUEUE_PRIORITY_HIGH: 高
//DISPATCH_QUEUE_PRIORITY_DEFAULT: 默认
//DISPATCH_QUEUE_PRIORITY_LOW: 低
//DISPATCH_QUEUE_PRIORITY_BACKGROUND: 后台
//参数2: 为未来做准备, 一般写0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"%@", globalQueue);
(3)自定义队列
//参数1: 队列的标识符
//参数2: 并发或串行
//并发: 并发数>= 2, DISPATCH_QUEUE_CONCURRENT, 第二个任务无需等待第一个任务完成
//串行: 并发数 = 1, DISPATCH_QUEUE_SERIAL, 第一个任务执行完, 第二个任务才开始
dispatch_queue_t customQueue = dispatch_queue_create("com.lanou.18", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"%@", customQueue);
//异步执行
//参数1: 放到哪个队列中
//参数2: 执行什么操作
//block中不能够使用self
__block RootViewController *blockSelf = self;
dispatch_async(globalQueue, ^{
[blockSelf food];
});
//同步执行
dispatch_sync(customQueue, ^{
[blockSelf food];
});
//延迟执行, 10秒后
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//执行的操作
NSLog(@"123");
});
6.多线程常见的问题
//多个线程的管理
//当多个线程同时管理一块资源时, 如果不进行管理, 会出现抢夺资源的现象, 为了避免这种现象, 使用锁来解决
//NSLock, 锁, 继承NSObject
NSLock *lock = [[NSLock alloc] init];
//加锁 和 解锁
- (void)sale {
while (YES) {
[NSThread sleepForTimeInterval:0.3];
//加锁
[lock lock];
if (ticketCount > 0) {
ticketCount--;
saleCount++;
NSLog(@"%@窗口卖了第%ld张, 剩余%ld张", [NSThread currentThread].name, saleCount, ticketCount);
} else {
NSLog(@"票已售完!");
return;
}
//解锁
[lock unlock];
}
1.UIView动画
//UIView动画, 实质是对CALayer动画的封装
(1)属性动画
//UIView动画影响的属性有: (1)frame 视图框架 (2)center 视图位置 (3)bounds 视图大小 (4)alpha 视图透明度 (5)backgroundColor 背景颜色 (6)transform 视图转换
//属性动画, 在做动画的期间改变视图的属性
//属性动画实现方法
- (void)propertyAnimation {
//动画块
//以 准备动画 开始
[UIView beginAnimations:@"annimation" context:NULL];
//配置动画属性
//动画时长, 默认0.2秒
[UIView setAnimationDuration:1];
//延时执行, 默认0秒
[UIView setAnimationDelay:0.1];
//重复次数
[UIView setAnimationRepeatCount:1];
//速度曲线
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//动画反转
[UIView setAnimationRepeatAutoreverses:NO];
//设置delegate
[UIView setAnimationDelegate:self];
//设置将要开始执行的方法
[UIView setAnimationWillStartSelector:@selector(willStart)];
//设置动画已经结束执行的方法
[UIView setAnimationDidStopSelector:@selector(didStop)];
//中间写 修改的属性值(frame, center, bounds, backgroundcolor, alpha, tranfrom)
animationView.frame = CGRectMake(72, 102, 232, 444);
animationView.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255. green:arc4random() % 256 / 255. blue:arc4random() % 256 / 255. alpha:0.8];
//transform, 变形
//CGAffineTransform, 结构体类型
//缩放
animationView.transform = CGAffineTransformMakeScale(0.5, 2);
//旋转
animationView.transform = CGAffineTransformMakeRotation(M_PI_2);
//矩阵变形
//animationView.transform = CGAffineTransformMake(1, 1, 1, 1, 1, 1);
//移动
animationView.transform = CGAffineTransformMakeTranslation(100, 10);
//在原有基础上缩放
//animationView.transform = CGAffineTransformScale(animationView.transform, 0.5, 2);
//在原有的基础上旋转
animationView.transform = CGAffineTransformRotate(animationView.transform, M_PI_4);
//在原有的基础上移动
animationView.transform = CGAffineTransformTranslate(animationView.transform, 20, 50);
//以 提交动画 结束
[UIView commitAnimations];
***//block
[UIView animateWithDuration:1 animations:^{
animationView.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255. green:arc4random() % 256 / 255. blue:arc4random() % 256 / 255. alpha:0.8];
}];
[UIView animateWithDuration:1 animations:^{
animationView.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255. green:arc4random() % 256 / 255. blue:arc4random() % 256 / 255. alpha:0.8];
}completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
[UIView animateWithDuration:1 delay:1 options:UIViewAnimationOptionCurveEaseIn animations:^{
animationView.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255. green:arc4random() % 256 / 255. blue:arc4random() % 256 / 255. alpha:0.8];
}completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
//调用方法
[self propertyAnimation];
(2)过渡动画
- (void)transitionAnimation {
//动画块
[UIView beginAnimations:@"transition" context:NULL];
//参数1: 设置过渡样式
//参数2: 对哪一个试图进行动画
//参数3: 是否需要缓存
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:animationView cache:NO];
[UIView commitAnimations];
***//block
//注: fromView这个视图会被移除
[UIView transitionFromView:endView toView:animationView duration:1 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished) {
}];
//注: 属性动画和过渡动画可以同时执行
}
//在button调用方法
[self transitionAnimation];
2.CALayer
(1)CALayer和UIView的区别
//1.UIView负责视图的位置和大小
//2.CALayer负责视图的绘制和显示
//3.每一个UIView都有一个只读属性layer
//4.UIView可以进行交互, CALayer不能交互
(2)CALayer的属性
//CALayer, 继承于NSObject
aLayer = [[CALayer alloc] init];
aLayer.frame = CGRectMake(88, 100, 200, 200);
aLayer.backgroundColor = [UIColor blueColor].CGColor;
//CGColor转UIColor
//[UIColor colorWithCGColor:...];
//常用属性
//圆角
aLayer.cornerRadius = 100;
//消除边缘锯齿
aLayer.allowsEdgeAntialiasing = YES;
//边框
aLayer.borderWidth = 5;
aLayer.borderColor = [UIColor whiteColor].CGColor;
//阴影
aLayer.shadowOpacity = 1.0;
aLayer.shadowOffset = CGSizeMake(10, 10);
aLayer.shadowColor = [UIColor purpleColor].CGColor;
[self.view.layer addSublayer:aLayer];
[aLayer release];
(3)CALayer动画
//CAAnimation, 抽象基类, 继承于NSObject
//CAPropertyAnimation, 属性动画, 继承于CAAnimation, 抽象子类, 通常我们使用它的两个子类CABasicAnimation和CAKeyframeAnimation
//CABasicAnimation, 基本动画
//调用下面的方法
[self basicAnimation];
//CAKeyframeAnimation, 关键帧动画
//调用下面的方法
[self keyframeAnimation];
//CATransition, 过渡动画
//调用下面的方法
[self transition];
//CAAnimationGroup, 组动画
//调用下面的方法
[self animationGroup];
//基本动画方法
- (void)basicAnimation {
//KVC, key-value coding
//key-Path: 想要修改的属性名
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"bounds.size.width"];
//动画时长
basic.duration = 3;
//重复次数
basic.repeatCount = 2;
// basic.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)];
// basic.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 400, 400)];
//fromValue, toValue, byValue 最多只能设置2个
basic.fromValue = @100;
basic.toValue = @400;
//添加动画, 并设置动画的标识符
[aLayer addAnimation:basic forKey:@"changeBounds"];
}
//关键帧动画方法
- (void)keyframeAnimation {
CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size.height"];
keyframe.duration = 5;
keyframe.values = @[@100, @500, @300, @111, @600];
//keyTimes元素的个数和values相等, 元素的值取值范围[0.0, 1.0], 并且元素值是递增
keyframe.keyTimes = @[@.2, @.3, @.7, @.8, @.9];
[aLayer addAnimation:keyframe forKey:@"height"];
}
//过渡动画方法
- (void)transition {
CATransition *transition = [CATransition animation];
//动画类型
transition.type = @"pageCurl";
//动画方向
transition.subtype = kCATransitionFromTop;
transition.duration = 2;
[aLayer addAnimation:transition forKey:@"transition"];
}
//组动画方法
- (void)animationGroup {
CABasicAnimation *basic= [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
basic.duration = 2;
basic.fromValue = (id)[UIColor redColor].CGColor;
CABasicAnimation *basic1 = [CABasicAnimation animationWithKeyPath:@"bounds"];
basic1.duration = 2;
basic1.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 500)];
CAAnimationGroup *group = [CAAnimationGroup animation];
group.duration = 2;
group.animations = @[basic, basic1];
[aLayer addAnimation:group forKey:@"group"];
}