微博笔记:数组
1.LaunchScreen浏览器
/*缓存
*LaunchScreen:替代之前的启动图片安全
*好处:服务器
*1.能够展现更多的内容session
*2.仅仅须要一张大尺寸的图片就好,而后伸缩适应图片app
*框架
*启动的优先级:异步
*启动图片的优先级低于 < LaunchScreen (图片不适合时记得调一下伸缩)ide
*
* 当模拟器尺寸不对的时候,第一时间找启动图片,模拟器的尺寸由启动图片决定(使用启动图片不用Xib的时候记得调整Info.plist 加载launchScreen的名称删掉)
*/
2.-----------------------------
//显示窗口
[self.window makeKeyAndVisible];
//makeKeyAndVisible 等价于,可是application.keyWindow = self.window只读
//1.application.keyWindow = self.window;
// 2.self.window.hidden = NO;
3viewController的加载顺序——————————————————
//1.UITabBarController 的View 是在UITabBarController控制器一建立就加载
//2.UIViewController 的View是在加显示窗口的才加载显示,(用到的才会显示,属于懒加载(须要用到的时候才会加载))
4 instancetype————————————————————
//instancetype:默认会识别哪一个类和子类调用,默认就会转为对应的类的对象
5.id-----------------------------
id (不建议使用):
1.使用这个不能使用点语法
2.全部的Set 和 Get 方法都能使用 ,不能识别出错误
6.Dictionary 的新语法
dic[NSForegroundColorAttributeName] = [UIColor orangeColor];
//上面的等价于下面的着这种方法,键 = Value ,key的值直接在 UIKIT中找
[dic setValue:[UIColor orangeColor]forKey:NSForegroundColorAttributeName];
7.appearance 的介绍和使用特色————————————
//appearances何时能够获获取外观标识,当这个类遵循UIAppearance协议的时候,好比:UIView
//获取全部的tabBarItem appearance:为全局外观的标始(不够严谨,会影响全部遵循UIAppearance协议的)
// UITabBarItem *item = [UITabBarItem appearance];
//self ->XDTabBarController
//获取当前类下面的全部TabBarItem
UITabBarItem *item = [UITabBarItem appearanceWhenContainedIn:self, nil];
//设置模型的文本属性
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
dic[NSForegroundColorAttributeName] = [UIColor orangeColor];
//上面的等价于下面的着这种方法,键 = Value ,key的值直接在 UIKIT中找
//[dic setValue:[UIColor orangeColor] forKey:NSForegroundColorAttributeName];
[item setTitleTextAttributes:dic forState:UIControlStateSelected];
//--------------------+(void)load 何时调用和做用-------
//何时调用:程序一启动的时候就会把全部类加载到内存
//做用:加载全部的类
//+(void)load
//{
//
//}
//———————+(void)initialize何时调用和做用----------
//何时调用:初次使用某个类或者子类的时候调用
//做用:初始化类
+(void)initialize
{
}
//获取TabBar 全局外观属性,设置外观属性,设置文字属性
//appearance:是一种协议 只要遵循 :UIAppearance就能够 因此当前的类归本身管理,使用appearanceWhenContainedIn
UITabBarItem *item = [UITabBarItem appearance];
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
attributes[NSForegroundColorAttributeName] = [UIColor orangeColor];
[item setTitleTextAttributes:attributes forState:UIControlStateSelected];
//———————设置中间的按钮的位置
//设置中间的按钮的位置
self.plusButton.center = CGPointMake( w * 0.5, h * 0.5);
//self.plusButton.bounds = CGRectMake(0, 0, self.plusButton.currentBackgroundImage.size.width, self.plusButton.currentBackgroundImage.size.height);
//默认的按钮大小与背景图片同样
//sizeToFit 会根据你的背景图片 ,Image和文字计算出最合适的位置
[addButton sizeToFit];
//————————item 模型的 求法
//self.items 是UITabBarItem 的模型 ,有多少个子控制器就有多少个Item模型
//————————TitleView 设置为搜索框—————
1.若是要求在左边显示提示文字 ,则要使用可使用占位符的,用UITextFile 代替 UIsearch ,要设置它的UITextFiled 的左边搜索按钮,则要设置 它的leftView , 可是要求有必定的距离,则先拉伸 ,在让图片自我调节位置。当设置UITextFiled 的上的左右视图时 :leftViewMode 必定要设置它的状态
//self( UITextFiled )
//initWithImage:图标的大小会默认与图片同样
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"searchbar_textfield_search_icon"]];
imageView.width += 10;
imageView.contentMode = UIViewContentModeCenter;
self.leftView = imageView;
//必定要设置,想要显示左边的视图,必定要设置左边的视图模式
self.leftViewMode = UITextFieldViewModeAlways;
//————隐藏底部的标签栏————
//当Push 的时候隐藏底部的标签栏
//hidesBottomBarWhenPushed:的前提条件是,system 自带的才可使用
self.hidesBottomBarWhenPushed = YES;
//———————————建立XIb initWithNibName的实现步骤
//1.先查看是否有XDOneView.xib的文件
//2.第二步加载与控制器同名的XDOneViewController.xib 文件
//建立一个默认几乎的透明的View
XDOneViewController *one = [[XDOneViewController alloc]initWithNibName:nil bundle:nil];
//等价于,由于init 它的底层会调用 initWithNibName
XDOneViewController *one = [[XDOneViewController alloc]init];
------------------------------------------------------------------------------------------------------------
//—————统同样式的左右导航按钮的时候———
1.要在继承(UINavigationController)导航控制器d的类中,利用
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (self.viewControllers.count != 0) {//不是跟视图控制器
//设置导航栏的内容
//设置导航控制左右两边的按钮
//左边的按钮
//当设置的左边的返回按钮覆盖之后,不能实现滑动返回手势功能
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"navigationbar_back"] highImage:[UIImage imageNamed:@"navigationbar_back_highlighted"] target:self action:@selector(backToPre) forControlEvents:UIControlEventTouchUpInside];
//右边的按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"navigationbar_more"] highImage:[UIImage imageNamed:@"navigationbar_more_highlighted"] target:self action:@selector(backToRoot) forControlEvents:UIControlEventTouchUpInside];
}
// CZLog(@"%s",__func__);
[super pushViewController:viewController animated:animated];
}
#pragma mark 导航控制器左右两边的Item UIBarButtonItem Action
-(void)backToPre
{
[self popViewControllerAnimated:YES];
}
-(void)backToRoot
{
[self popToRootViewControllerAnimated:YES];
}
2.当返回按钮被覆盖的时候,返回滑动手势则会失效
1.要在继承(UINavigationController)导航控制器d的类中,viewDidLoad中设置它的导航控制器代理
- (void)viewDidLoad {
[super viewDidLoad];
//保存原来的滑动手势代理
_popDelegate = self.interactivePopGestureRecognizer.delegate;
//导航控制器上的代理方法,实现判断是否回到跟控制器
self.delegate = self;
}
//2.调用调用带有展现当前的ViewController 的代理方法,何时使用系统的滑动手势代理方法,何时不适用
#pragma mark -------popDelegate
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(@"%@",self.viewControllers[0]);//判断它是哪个控制器
if (viewController == self.viewControllers[0]) {//显示的是跟控制器
//还原滑动返回手势
self.interactivePopGestureRecognizer.delegate = _popDelegate;
}else//不显示根视图控制器
{
//实现滑动返回功能
//清空滑动返回收手势代理,就能实现返回滑动功能
self.interactivePopGestureRecognizer.delegate = nil;
}
}
------------------------------------------------------------------------------------------------------------
//------------能够循环利用的两个的中, TableView 与 colletionView
它们添加内容都是调用ContentView,
//检查是否有新的版本
//若是有新特性,进入新特性界面
//还有必定要对CollectionView ,进行LayOut
------------------------------------------------------------------------------------------------------------
//1.获取版当期的版本号
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleVersion"];
//2.获取上一次的版本号
NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:XDVersionKey];
//3.判断版本号,是否要新定义
if ([currentVersion isEqualToString:lastVersion]) {//当前版本号和上一次相同
//建立tabBarController ,把它做为根视图控制器,支持设备旋转
XDTabBarController *tabBarController = [[XDTabBarController alloc] init];
self.window.rootViewController = tabBarController;
}else{//当前版本号和上一次的不相同,要重新特性界面进入
XDNewFeatureController *newFeatureVC = [[XDNewFeatureController alloc] init];
self.window.rootViewController = newFeatureVC;
//保存当前的版本号,用编号设置
[[NSUserDefaults standardUserDefaults]setObject:currentVersion forKey:XDVersionKey];
}
//—————————偏好设置的优势————————
//偏好设置存储的好处
//1.不用本身管理文件名
//2.快速进行键值对存储
//———————————OAuth受权———————
OAuth受权:让数据变得更安全
流程:有数据提供商提供一个登录网站,显示在第三方客户端上
何时须要UAuth受权:1.须要获取第三方数据(新浪,腾讯,百度,豆瓣)
2.第三方登陆
3.第三方分享
注意:并非任何软件都能OAuth受权,只有成为第三方的开发者,才能UAuth受权
如何成为第三方开发者?
//1.在百度上搜索 微博开放平台
//2.登陆本身的微博帐号
//3.点击微连接,选择移动开发,实名认证之后,点击继续建立
//4.高级信息中填写OAuth受权设置
//——————OAuth 受权的步骤——————
受权步骤总结:
1.获取未受权的Request Token<进入登录界面>拼接的时候记得不要留空白
2.获取用户受权的Request Token <点击受权>
3.用受权的 Request Token 换取 Access Token
(获得这个 Access Token 就至关于获得一个“令牌”,经过此”令牌“请求
就能够拥有资源的网站抓取任意有权限被抓取的资源)
access_token:表示哪一个软件在哪一个用户下的标志符,获取了access_token就能够获取相应的数据提供商提供的数据
uid:表示用户的惟一标识符
//———开发步骤———————
1.搭建开发界面
2.展现数据
3.处理对应的业务逻辑
//—————————content-type:响应头的错误----
/*
"Request failed: unacceptable content-type: text/plain"
1.AFN经过判断响应头,判断是否有解析数据的方式,content-type: 包含在响应头中,因此要修改AFN,让其包含text/plain解析方式
*/
//———KVC的底层
1.一个一个的遍历Key ,查找是否有 SetKey ,若是有的话直接赋值
2.看是否有_key,若是有的话找到直接赋值
3.遍历全部的key,给key 赋值
4.若是key没有赋值,就会报错
//————跟服务器打交道
1.向服务器发送请求 -->通常的参照接口文档,跟接口文档打交道,就查阅接口文档(1.请求的Url 2.哪一种类型的接口(GET,Post)3.返回的数据格式)
2.服务器响应的数据-->解析数据,设计数据模型—>返回数据转换为模型
3.展现数据,刷新数据
//———————使用SDWebImage 的好处和注意点
SDWebImage 的好处:
1.属于异步请求,不会阻塞主线程(界面)
2.自动建立缓存
3.可让图片循环利用
注意点:由于自动建立缓存,很容易形成内存的警告
解决的方法:
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
//中止全部的图片下载
[[SDWebImageManager sharedManager] cancelAll];
//清空全部缓存
[[SDWebImageManager sharedManager].imageCache clearMemory];
}
//———下拉刷新数据 ,下拉添加更多的数据
//添加下拉刷新控件
[self.tableView addHeaderWithTarget:self action:@selector(loadNewStatus)];
//自动刷新微博数据
[self.tableView headerBeginRefreshing];
//结束下拉刷新
[self.tableView headerEndRefreshing];
//最新数据的条数
NSIndexSet *indexSets = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,statuses.count)];
//把最新的微博插入到前面,必定要数组的形式添加数据
[self.statuses insertObjects:statuses atIndexes:indexSets];
//添加上拉刷新控件
[self.tableView addFooterWithTarget:self action:@selector(loadOtherStatus)];
//since_id false int64 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。
if (self.statuses.count) {//有微博数据,须要下拉刷新
params[@"since_id"] = [self.statuses[0]idstr];
}
//max_id false int64 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。,默认为0。
1.注意点:必定要记得“-1”把重复的数据去掉
if (self.statuses.count) {//有数据须要上拉获取(之前)更多的数据
long long max_Id =[[[self.statuses lastObject] idstr]longLongValue]-1;
params[@"max_id"] = [NSString stringWithFormat:@"%lld",max_Id];
}
//结束下拉刷新
[self.tableView footerEndRefreshing];
//不能使用addObjects: 必须把数组的元素加入
[self.statuses addObjectsFromArray:statuses];
//请求数据常规的开发步骤
1.查看接口文档
2.依据参数列表,设置参数模型
3.依据结果列表设置结果模型
4.拿到对应的工具类请求就好
//设置软件的消息未读数
//设置应用程序的未读数,记得要注册通知
[UIApplication sharedApplication].applicationIconBadgeNumber =接收到消息数目( result.totalCount);
1. applicationIconBadgeNumber 查看它的头文件
2.从头文件中能够知道它是对象 注册[UIApplication registerUserNotificationSettings:]
3.在程序的启动页面,AppDelegate 写
//注册微博程序未读消息通知
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[application registerUserNotificationSettings:settings];//经过这里能够推出要有UIUserNotificationSettings 对象的属性
//点击tabBar Item 的时候 刷新微博 的逻辑 :不要当选中第一个按钮的时候都刷新,当本身想跳转到其余页面,再次点击刚刚的按钮的时候,又刷新,那原来的浏览的消息界面就改变了,因此要知足 两次选中的仍是同一个按钮的时候才刷新 index == 0(这是指定) && self.selectedIndex == index
//让程序一直处于运行,在后台播放
//在真机的话要记得设置音频会话
[/*
//混合播放,会把后台的音乐混合播放
AVF_EXPORT NSString *const AVAudioSessionCategoryAmbient;
//单独播放,会先把后台的音乐先停下来,而后再播放
AVF_EXPORT NSString *const AVAudioSessionCategorySoloAmbient;
//进入后台就播放
AVF_EXPORT NSString *const AVAudioSessionCategoryPlayback;
*/
//在真机的后台播放音乐
AVAudioSession *session = [AVAudioSession sharedInstance];
//设置会话的类型,能够两种类型一块儿设置
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
[session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
//激活
[session setActive:YES error:nil];
]//这是加载程序的时候就设置
//程序即将失去焦点的时候调用
- (void)applicationWillResignActive:(UIApplication *)application {
//设置播放器
NSURL *url = [[NSBundle mainBundle] URLForResource:@"一次就好.mp3" withExtension:nil];
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
//准备播放
[player prepareToPlay];
//无限播放
player.numberOfLoops = -1 ;
//播放
[player play];
//记得局部变量都要,强引用
_player = player;
}
//当程序进入后台的时候调用
- (void)applicationDidEnterBackground:(UIApplication *)application {
//开启一个后台任务,时间不肯定,优先级比较低,假如系统要关闭应用的时候,系统会优先关闭这个程序
UIBackgroundTaskIdentifier ID =[application beginBackgroundTaskWithExpirationHandler:^{
//结束后台的任务
[application endBackgroundTask:ID];
}];
//1.如何提升后台的优先级,欺骗苹果,设置播放程序
//2.苹果系统会检测是否在播放音乐,当没有在播放音乐的时候,系统会关闭程序
//3.微博:在即将失去焦点的时候会播放静音的音乐
}
//—————复杂的界面的开发步骤——————
1.按照业务逻辑划分界面的结构(原创,转发,工具条)
2.每个结构都自定义控件
3.在控件上先把全部划分的结构界面都添加上去
4.计算每一个控件的位置,若是之后碰到的内容是根据模型决定的,立刻就搞个ViewModel视图模型(模型 + 控件的Frame)
5.模型转视图模型
6.给控件赋值视图模型
7.调节界面(文字和颜色)
//UIImageView 的 contentMode
UIViewContentModeScaleToFill,//填充整个控件
UIViewContentModeScaleAspectFit,//按比例缩放,且不会超出控件
UIViewContentModeScaleAspectFill, //按比例缩放,且高度或则宽度有一个不超出控件,而后让图片的中心对齐控件中心
UIViewContentModeCenter,//不会缩放图片,只会把图片的中心点和控件对齐
//-------获取服务器的图片的时候,若是不清晰的话
http://ww1.sinaimg.cn/thumbnail/61c99730jw1eyndx74f8pj20tz124aik.jpg
http://ww1.sinaimg.cn/bmiddle
/61c99730jw1eyndx74f8pj20tz124aik.jpg
//当记不住Block 的格式时候 在 代码中敲 :inline 就会显示
**********************************************************
//当设置复杂的cell仍是其余的先要划分结构,有哪几部分组成,划分红子控件(注意点:cell 的初始化 initWithStyle)
1.先搭建框架
2.搭建子类控件
*****************************************************************************************************
//重写建立Cell ,自定义建立cell:使用类方法
+(instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"cell”;
//放回的cell 是否为闲置
id cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
//谁调用就初始化谁的类
cell = [[self alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
return cell;
}
*****************************************************************************************************
MVVM思想:
/*
1.cell的高度应该提早计算出来: 当一有数据的时候就要使用VM 设置Cell的大小
2.cell 的高度 必须计算每一个cell的子控件必须frame,才能够肯定(相似字体的话,你经过字体的小设置Frame的同时,记得要设置控件的字体)
2.在cell的setStatus方法计算cell的高度,会比较耗费性能
解决的办法:MVVM思想
M:模型
V:视图
VM:视图模型,(模型中包装模型+模型对应视图的Frame)
*/
/*
复杂的界面开发步骤:
1.按照业务逻辑划分结构,(原创,转发,工具条)
2.每个结构,都自定义一个控件
3.在控件上先把全部划分的结构添加上去
4.计算每一个控件的位置,若是遇见的内容是根据模型决定的,立刻定义一个ViewModle(模型+模型的大小)
5.模型转视图模型
6.赋值
7.调节界面(文字大小,颜色)
8.一个结构一个结构的处理
*/
/*
1.能够直接传递数据,肯定数据的放置的位置
2.MVVM:若是一个控件循环利用,能够避免屡次计算控件的Frame
*/
*****************************************************************************************************
经常使用的图片大小
1.导航条的 高度:64点 @2x :128 @3x : 192
2.tabBar的高度: 49点
3.导航条的子控件和tabBar 的子控件 Or 工具条的高度:35
*****************************************************************************************************
开发中注意的事项
1.UIView 是设置不了 图片的,那先要转变成:UIImageView 这能够添加图片,可是要注意,记得设置交互
self.userInteractionEnabled = YES;
2.设置每个cell 间的间距,不能够整个cell设置由于没有设置它的 X Y 是不肯定的,因此能够设置cell 中的原创微博 的高度 下移 10 个间距 ,在设置tableView 的背景颜色就好
*****************************************************************************************************
时间的业务逻辑:(使用的框架为:NSDate+MJ
)
//设置时间格式(因为使用点语法获取数据的,因此要从新设置Get方法)判断的技巧:不要从小的开始判断,要先判断大的,再依次判断小的
-(NSString *)created_at
{
// Sat Mar 26 16:05:03 +0800 2016 微博给咱们的时间格式
//1.先要把字符串转化成 NSDate
//转换 EEE MMM d HH:mm:ss Z yyyy
//日期格式转换
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"EEE MMM d HH:mm:ss Z yyyy ";
NSDate *creat_time = [formatter dateFromString:_created_at];
if ([creat_time isThisYear]) {//今年
//两天前
if ([creat_time isToday]) {//今天
NSDateComponents *cmp = [creat_time deltaWithNow];
if (cmp.hour >= 1) {
return [NSString stringWithFormat:@"%ld小时前",cmp.hour];
}else if(cmp.minute > 1)
{
return [NSString stringWithFormat:@"%ld分钟前",cmp.minute];
}else
{
return @"刚刚";
}
}else if ([creat_time isYesterday])
{//昨天
formatter.dateFormat = @"昨天 HH:mm";
return [formatter stringFromDate:creat_time];
}else
{//前天
formatter.dateFormat = @"MM-dd HH:mm";
return [formatter stringFromDate:creat_time];
}
}else{//不是今年
formatter.dateFormat = @"yyyy-MM-dd HH:mm";
return [formatter stringFromDate:creat_time];
}
return _created_at;
}
*****************************************************************************************************
图片的contentMode常用的介绍
/**
* UIViewContentModeScaleToFill :将整个图片压缩到适合控件的大小
UIViewContentModeScaleAspectFit :按比例缩放到不超出边框
UIViewContentModeScaleAspectFill:按比例缩放到到一边(宽或高)不超出边界合适就不在改变
UIViewContentModeCenter:view 与图片的中心点对齐,不会居中
*
*/
imageView.contentMode = UIViewContentModeScaleAspectFill;
//把多余的截掉
imageView.clipsToBounds = YES;
*****************************************************************************************************
//九宫格的布局
1.先求整体的Frame
//配图
if (_status.pic_urls.count) {
CGFloat photosX = textX;
CGFloat photosY = CGRectGetMaxY(_orignalTextFrame) + MDStatusCellMargin;
CGSize photosSzie = [self setPhotosSizeWithCount:_status.pic_urls.count];
_orignalPhotosFrame =(CGRect){{photosX,photosY},photosSzie};
originalH = CGRectGetMaxY(_orignalPhotosFrame) + MDStatusCellMargin;
}
//计算大小的方法setPhotosSizeWithCount
-(CGSize)setPhotosSizeWithCount:(NSInteger)count
{
//配图的列数
NSInteger cols = count == 4?2:3;
//配图行数(这是有计算公式的):行数 = (总数 - 1)/列数 +1;
NSInteger rols = (count - 1) / cols + 1;
CGFloat photosWH = 70;
CGFloat photosW = photosWH * cols + (cols - 1) * MDStatusCellMargin;
CGFloat photosH = photosWH * rols + (rols - 1)* MDStatusCellMargin;
CGSize photosSie = CGSizeMake(photosW, photosH);
return photosSie;
}
//计算九宫格内部布局
-(void)layoutSubviews
{
[super layoutSubviews];
CGFloat x = 0;
CGFloat y = 0;
CGFloat w = 70;
CGFloat margin = 10;
CGFloat h = 70;
int col = 0;
int rol = 0;
int cols = _pic_urls.count == 4?2:3;
//计算要显示的图片的Frame
for (int i = 0; i< _pic_urls.count; i++) {
col = i % cols;
rol = i / cols;
UIImageView *imageV = self.subviews[i];
x = col * (margin + w);
y = rol * (margin + h);
imageV.frame = CGRectMake(x, y , w, h);
}
}
*****************************************************************************************************
//图片浏览器设置
//添加九个配图控件(要把传过来,利用属性传值)
-(void)setUpAllChildVC
{
//九宫格中
for (int i = 0; i < 9 ; i++) {
UIImageView *imageView = [UIImageView alloc].init;
/**
* UIViewContentModeScaleToFill :将整个图片压缩到适合控件的大小
UIViewContentModeScaleAspectFit :按比例缩放到不超出边框
UIViewContentModeScaleAspectFill:按比例缩放到到一边(宽或高)不超出边界合适就不在改变
UIViewContentModeCenter:view 与图片的中心点对齐,不会居中
*
*/
//添加点图片手势按钮
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
imageView.tag = i;
//当使用UIImageView的时候,记得设置图片的交互
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:tap];
imageView.contentMode = UIViewContentModeScaleAspectFill;
//把超出边框的图片去掉
imageView.clipsToBounds = YES;
[self addSubview:imageView];
}
}
//添加点图片手势按钮
-(void)tapGesture:(UITapGestureRecognizer *)tap
{
//在手势的图片添加Tag,这能够知道获取的是第几张图片(经过手势能够获取点击的图片)
UIImageView *imageV = (UIImageView *) tap.view;
//点击图片的时候调用
//建立图片浏览器
int i = 0;
NSMutableArray *array = [NSMutableArray array];
for (MDPhotos *photos in _pic_urls) {
//将MDphotos 转换成 MJphoto
//在MJPhoto.h 的文件中 ,要实现的属性有
//1.@property (nonatomic, strong) NSURL *url;
//2.@property (nonatomic, strong) UIImageView *srcImageView; // 来源view(你点击那个图片)
//3.@property (nonatomic, assign) int index; // 索引
MJPhoto *mjPhotos = [[MJPhoto alloc] init];
//图片不清晰时,能够键链接的改一下
NSString *urlString = photos.thumbnail_pic.absoluteString;
urlString = [urlString stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
mjPhotos.url = [NSURL URLWithString:urlString];
// NSLog(@"%@",photos.thumbnail_pic);
mjPhotos.index = i ;
mjPhotos.srcImageView = imageV;
[array addObject:mjPhotos];
i ++ ;
}
MJPhotoBrowser *browser = [[MJPhotoBrowser alloc] init];
/*MJ头文件提示要实现的,之后使用框架的时候,要看头文件
// 全部的图片对象(MJPhoto)
@property (nonatomic, strong) NSArray *photos;
// 当前展现的图片索引
@property (nonatomic, assign) NSUInteger currentPhotoIndex;
*/
browser.photos = array;//全部图片对象
browser.currentPhotoIndex = imageV.tag ;
//之后看到要显示到主窗口的 能够 考虑框架是否有 show(看框架头文件)
[browser show];
}
*****************************************************************************************************UITextView 中输入的字体设置和水印的文字大小同样(textView 输入的位置x= 5,y = 8)
UITextView 系统没有默认设置self.font
经过设置:
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.font = [UIFont systemFontOfSize:13];
//self.placeHolderLable.font = font; 不要在这里设置,当外界改变(textView)的时候,也会改变
}
return self;
}
//再重写setFont设置placeHolderLable.font 能够跟着外面 改变
-(void)setFont:(UIFont *)font
{
[super setFont:font];
self.placeHolderLable.font = font;
//避免在输入信息后在设置字体,这样字体的大小不符合lable Frame
[self.placeHolderLable sizeToFit];
}
*****************************************************************************************************
becomeFirstResponder //变成第一响应,
resineFirstResponder //放弃第一响应,
响应机制多用在获取(或放弃)键盘行为
******************************************************************************
判断是否有文本输入的时候可使用通知
//监听文本的输入(通知)
/**
*1.addObserver:须要监听的对象
2.name:监听通知的名称
3.object:监听谁发送通知 nil:谁发送都监听
设置通知,要把它移除
UITextViewTextDidChangeNotification:这是监听输入名称(须要记住的)
*
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextViewTextDidChangeNotification object:nil];
}
-(void)textChange
{ //监听是否有文本输入
if (_textView.text.length) {//有文本输入
_textView.hiddlePalceHolder = YES;
}else
{//没有文本输入
_textView.hiddlePalceHolder = NO;
}
}
-(void)dealloc
{ //移除通知
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
*****************************************************************************
//设置图片的大小(有的图片上传的时候要大小限定)
CGFloat compressionQuality 这是图片压缩系数
UIImageJPEGRepresentation(<#UIImage *image#>, <#CGFloat compressionQuality#>)
//这是压缩图格式
NSData *data = UIImagePNGRepresentation(image);
*****************************************************************************
//自动布局行高
self.tableView.rowHeight = UITableViewAutomaticDimension;
tableView:dequeueReusableCellWithIdentifier
1.storyBoard 其实就是内部会帮你注册cell
2.在ViewDidLoad 使用了(forIndexPath:)没有使用storyBoard ,要本身手动建立 [self.tableView registerClass:[本身的建立cell类 class] forCellReuserIdentifer:ID ];
forIndexPath:不能使用本身建立的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath];
/*1.先从缓存池中取出数据
2.判断Cell 有没有注册,有的话,直接建立cell
3.没有建立就返回NIL