从2月12日开始到3月9日,一个月学习这个项目收获了很多知识点,给自己总结出来,方便以后查看。

  • 1.控制器的view加载完毕,首先在- (void)viewDidLoad方法中添加 下拉刷新 的控件;

    • 1.1将添加下拉刷新控件封装一个函数- (void)setupRefresh,该方法中添加MJRefresh框架的header控件
    • 1.2写一个头部控件调用的刷新方法- (void)loadNewTopics,里面写发送网络请求代码
  • 2.在成功返回的block中调用endRefreshing将Header控件隐藏起来,当然失败一样也要影藏起来;

  • 3.一进来TableView就应该自动刷新,所以在- (void)setupRefresh方法中添加完header控件,就调用它的 beginRefreshing方法,让其自动刷新;

  • 4.利用header的 automaticallyChangeAlpha(YES)属性自动改变header的透明度,让其影藏,解决下图效果问题

  • 5.利用MJRefreshAutoNormalFooter类添加footer控件,一开始设置footer控件hidden属性为YES隐藏;

    • 5.1MJRefreshAutoNormalFooter类的footer是上拉到指定位置自动刷新
    • 5.2 MJRefreshBackFooter类刷新完会有一个回弹的效果
  • 6.上拉刷新加载更多数据,所以将下拉刷新发送网络请求的代码同样复制一份到 - (void)loadMoreTopics方法中,但是加载更多需要下一个的页码参数

网络延迟中一些细节处理

  • 7.网络不好时,上拉加载更多失败了,但是page++了,下次加载就会直接跳过失败那页数据,所以在失败的block中将page—;

  • 8.加入显示处在第5页数据中,先在下拉刷新加载最新数据,但是也有可能失败,一旦下拉刷新page被清空为0了,但现在处在第5页,如果现在上拉刷新加载更多,将会重复加载第0页数据。所以改进办法就是当下拉刷新成功了,才将页码清空为0,将self.page = 0; 放到成功的block中;

  • 9.用户有可能下拉刷新又上拉刷新 例如:现在用户当前处在第5页,先下拉刷新,又上拉刷新,一会下拉刷新的数据回来后,page被清空为0了,之后上拉数据回来,成功后会将第六页数据放到第5页数据后,但是第5页数据被清空了,就讲最前面的0页数据和第6页数据合在一起了。如果上拉数据失败,page—,这样当前page被减为负数,也是有问题。 *两种解决办法

    • (1)控制器增加一个字典成员属性params,只处理最后一次的网络请求,如果当前返回的请求和params中的请求不是同一个请求,直接return
if(self.params != params) return;
复制代码
  • (2)禁止用户同时上拉和下拉刷新,如果发现有一个在刷新,则禁止掉例外一个刷新

  • 10.footer控件永远粘着cell的底部,如果一上来,TableView没有数据,那么会直接显示footer控件。所以创建完footer控件时,默认让其隐藏,同时在numberOfRowInSession中设置如果返回的count==0时隐藏

    复制代码

self.tableView.mj_footer.hidden = (self.topics.count == 0);

- 11.设置TableView内边距的一些代码放在“精华”控制器中不合适,应该放到TableView自己的控制器中,子控制器的代码应该放到子控制器- 12.在other文件中新建一个保存常量的类(继承NSObject),用来保存一些全局都用到的常量信息- 12.1 删除所有内容,导入.h和.m都导入 #import <UIKit/UIkit.h>- 12.2 .m中放一些const常量,.h中放一些放常量的引用同时加上 UIKIT_EXTERN- 13.修改TableView内部的Cell的尺寸,让其左右有间距,需要重写他的`setFrame`方法,只需要设置一次的东西就写在`awakeFromNib(xib)`,或`initWithFrame`(代码)方法中- 14.将createTtime字符串时间转变为`NSDate`格式的时间
```objc
NSDate *now = [NSDate date]; // 当前时间
NSDateFormat *fmt = [[NSDateFormat alloc] init];
fmt.dateformat = @“yyyy-MM-dd HH:mm:ss”;
NSDate *createtime = [fat dateWithString:topic.create_time];
复制代码
  • 15.两个时间的比较方法

    • (1):返回一个时间间隔(s)
NSTimeInterval delta = [now timeIntervalSinceDate:create];
复制代码
  • (2):NSCalendar类,有一个currentCalendar方法获取当前的日历
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger year= [calendar component:NSCalendarUnitYear fromDate:now];
复制代码

其中NSCalendarUnitYear是一个枚举,里面有年、月、日、时、分、秒components:fromDate:同上一样,可以传多个枚举值,返回一个NSDateCompoents,里面放着年、月、日、时、分、秒 时间的比较:

NSDateCompoents cmps =[calendar components:枚举 fromDate:create toDate:now options:0]
复制代码

cmps.year, cmps.month等就是相差的间隔。

  • 16.UITableView的Cell有一个TableView:heightForRowAtIndexPath:方法,直接动态计算出每一个Cell的高度,但是这个方法调用非常频繁,所以将具体计算代码放在这里会影响性能。应该给模型提供一个cellHeight属性,重写该属性的getter方法,将计算的代码放这里。并且加一个if判断,如果_cellHeight没有值,才进行计算,这样就保证只计算一次,提升性能。但是提供这样一个属性暴漏在外面,别人很有可能会修改属性,所以加上readonly。

  • 17.如果一个成员变量加了readonly,又重写了getter方法,那么getter方法中的成员变量就会报错,因为编译器认为有readonly的只生成getter方法,自己又实现了getter方法,意味着成员变量也需要自己实现,所以报错。这时,就需要我们自己再实现成员变量,在.m中加上_cellheight的成员变量。

  • 18.- boundingRectWithSize:options:attributes:context:方法是根据文字的大小、宽度,动态计算出这段文字的高度。

  • 19.iPhone默认是不支持gif图片播放的,必须将一个gif图片解析成n个UIImage对象才能进行播放,用到ImageIO框架

  • 20.imageView的contentMode属性中有一个UIViewContentModeScaleToFit属性,表示,缩放图片比例,在现有的显示尺寸的大小内,保证看到图片的全部。另外UIViewContentModeScaleToFill模式是,等比例伸缩,然后在现有显示尺寸的大小内,显示伸缩后的图片的中间部分,但是剩余的头尾剩余部分也会显示出来,会遮盖其他控件,所以在显示图片的iamgeView右侧栏中间的模式中,勾选Clip Subviews即可将多余的部分裁剪掉。

  • 21.带有图片的段子,为了提高用户体验,在图片没有下载完之前,

    • 1.先显示占位图片;
    • 2.提供一个下载的进度条;
  • 22.屏蔽第三方框架带来的风险,就是自己建立一下类,然后继承自框架的类,这样面向自己类做开发,以后如果不用这个框架了只需要改这个类即可,这样减少不用框架后多处修改代码的风险

  • 23.-(void)UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SELcompletionSelector, void *contextInfo ); 用来将图片保存进用户的相册,第一次调用会弹框询问。

  • 24.图片段子中的图片,自定义一个UIView类,继承UIView,提供一个类方法返回一个创建好的UIView, ```objc [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];


- 25.根据模型的内容(图片、声音or视频?),将UIView添加到对应的cell中,所以在模型属性的setter方法中写;- 26.为了保证只创建一次UIView,Cell来回滚动时可以循环利用,所以采用懒加载,但是控件都是弱指针,代码段执行完控件就死了,所以在懒加载中直接将控件下到contentView中- 27.图片段子中的图片,需要给自定义的图片View增加一个topic模型,然后在if判断中若为图片段子则将topic模型传递给图片view的模型中,这样view才能拿到数据,设置数据到对应的view中去显示- 28.如果Cell的尺寸做了修改,Cell内部的子控件frame尺寸不对,则将autoresizingMask属性设置为NOself.autoresizingMask = UIViewAutoresizingNone;- 29.判断gif图片标志的显示或隐藏
```objc// 判断GIF是否显示NSString *extensionName = topic.large_image.pathExtension;self.gifView.hidden = ![extensionName.lowercaseString isEqualToString:@"gif"];
复制代码
  • 30.在不知道图片扩展名的情况下,SDWebImage框架中有一个方法,可以取出图片数据的第一个字节,进行判断,获得图片的扩展名,这种方式是最准确的

  • 31.发布按钮点击后,一进来,几个button在执行动画的过程中,应该让按钮不能被点击,所以在控制器的viewDidLoad方法中设置self.view.userInteractionEnabled = NO; (不响应用户交互事件),动画执行完毕(最后标语落下来时),在setCompetionBlock这个block中恢复view的点击事件;

  • 32.UIWindow有三个级别,Normal < StatusBar < Alert 依次升高。如果想做一个动画,在状态栏提示一些东西,就创建一个Window,设置为状态栏级别,挡住系统自带的状态栏,因为状态栏就是一个StatusBar级别的window。

  • 33.命名规范

    • (1)成员变量访问以下滑线开头;
    • (2)全局变量可以在名称后面加一个下划线与成员变量区分;
    • (3)如果没有任何东西就是局部变量
  • 34.发布按钮,一进来动画在执行的过程中,让下降的按钮应该不能被点击,所以在viewDidLoad中让view.userInteractionEnabled = NO,在动画执行完毕后再恢复能点击,在 setCompletionBlock:^的block中恢复

  • 35.reloadData刷新表格时就会调用数据源的三个方法

   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
复制代码
  • 36.header和cell一样也可以循环利用 dequeueReusableHeaderFooterViewWithIdentifier:利用这个方法从缓存池中找这个标识的headerfooterView,返回一个UITableViewHeaderFooterView

  • 37.从iOS8开始提供了一个自动计算Cell高度尺寸的属性,先给出估算高度,然后让真实高度根据具体尺寸伸缩

    self.tableView.estimatedRowHeight = 44;self.tableView.rowHeight = UITableViewAutomaticDimension;
复制代码
  • 38.连续点击两次tabBar自动刷新当前窗口中的TableView,是有通知完成,系统的delegate成为tabBarController的代理,当tabBar被点击时,发出一个通知。对应的TableViewController接到通知,调用自己的头部控件开始刷新

  • 39.UIView没有图片属性,也没有背景图片属性,所以要给UIView添加背景需要调用drawRect:方法画上去

  • 40.监听textFiled的文字改变可以用三种方法:

    • (1)代理 - 成为代理——>遵守协议——>实现方法 (不推荐)
    • (2)通知 有一个UITextFiledDidChangeNotification
    • (3)addTarget textFiled继承自UIControl
  • 41.从iOS7以后

[[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStyleDone target:self action:@selector(cancel)];
复制代码

style样式写什么都一样

  • 42.设置导航控制器view上的标题文字大小的两种方式

    • (1)UIViewController被导航控制器包装后拿到titleView属性,自己包装一个UIView,里面放一个Label将文 字调整一下 self.navigationItem.titleView
    • (2)拿到 navigationBar属性,在navigationController的initialize方法中设置
[self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:20]}];
复制代码
  • 43.如果在navigatioController利用appearance分状态修改了UIBarButtonItem的属性,那么在控制器中设置 rightBarButtonItem状的enabled的属性之后,要调用layoutifNeeded函数强制刷新
[self.navigationController.navigationBar layoutIfNeeded];
复制代码
  • 44.UITextView没有占位文字,可以自定义一个继承自UITextView,增加一个placeholder属性的UITextView,方法有两种:

    • (1)实现 - (void)drawRect:(CGRect)rect 将文字画上去
    • (2)给TextView增加一个子控件Label,来显示占位文字,好处是,子控件可以在textView实现滚动效果
  • 45.监听UITextView的文字改变有很多中方法

    • (1)通过代理,有一个TextViewDidChange:方法可以监听文字的改变,但是不推荐这种方法,因为控制器要成为代理来监听控件的改变,高耦合性,占位文字是控件内部的功能,应该由自己来控制或隐藏
    • (2)TextView文字发生改变会发出通知UITextViewDidChangeNotification
  • 46.如果监听了通知,一定要调用dealloc方法,将监听删除

  • 47.文字一旦改变就会调用监听方法,在监听方法中调用setNeedsDisplay方法重新绘制,因为setNeedsDisplay会调用DrawRect:方法,该方法每次进来会将之前的内容擦掉,重新绘制一次

  • 48.UITextView给别人提供一个占位文字的属性,别人很有可能随时更改这个属性值,所以要重写属性的setter方法,时时监听属性的修改,需要重写以下几个方法,同时都要调用setNeedsDisplay方法

    • (1) 重写占位文字的属性方法
    • (2) 重写字体属性的setter方法,因为字体别人也有可能修改,同样也要调用
    • (3) 别人可能通过代码修改text值,所有也要重写setText:方法(调用父类的该方法)
    • (4)别人修改的也有可能是富文本属性AttributedText,所有这个属性也要重写
  • 49.TextView继承UIscrollView,所以他是能滚动的,其中有一个属性alwaysBounceVertical,在竖直方向上有弹簧效果

  • 50.增加的label采用懒加载先确定位置,如果label的宽度确定,高度是要通过文字计算出来,所以在layoutSubviews方法中计算根据文字数量和字体大小确定后的label的尺寸,但是控制器中有可能随时修改这个尺寸和文字,所以要在setter方法中调用setNeedsLayout方法在恰当的时间重新计算更新后的label的尺寸

/***  更新label的尺寸*/
- (void) layoutSubviews
{CGSize size = CGSizeMake( self.width - 2 * self.phLabel.x, MAXFLOAT);self.phLabel.size = [self.placeholder boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.font} context:nil].size;
}
复制代码
  • 51.setNeedsDisplay会在恰当的时候调用drawRect:方法 setNeedsLayout会在恰当时候调用layoutSubviews方法

  • 52.通过代码设置创建按钮的尺寸和图片的尺寸一样的方法

    • (1)button.size = [UIImage ImageNamed:@“tag_add_icon”].size;
    • (2)取出普通状态下的图片 button.size = [button iamgeForState:UIControlStateNormal].size;
    • (3)获取正在展示的图片 button.size = button.currentImage.size;
  • 53.一旦根控制器modal出一个控制器,就会用presentedViewController属性引用着它。

    • a.presentedViewController -> b a控制器的这个属性可以找到弹出的b控制器
    • b.presentingViewController -> a b控制器的这个属性可以找到谁把他push出来了
  • 54.监听TextFiled的文字改变的三种方法:

    • (1)代理方法,但对中文的支持不好,不推荐
    • (2)通知 UITextFieldTextDidChangeNotification
    • (3)addTarget:方法
  • 55.按钮的contenMode属性用在内部的image身上,对文字的对齐方式不起作用, contentHorizontalAlignment属性,是设置按钮内部文字或图片水平方向的排布

  • 56.右下角的换行不是字符,所以不能通过addTarget:方法中的点击方法监听,要通过代理监听

- (BOOL)textFieldShouldReturn:(UITextField *)textField
复制代码
  • 57.- (void)deleteBackard是监听键盘的删除按键

  • 58.自己定义的Block很容易发生循环引用,所以一定要用弱引用

  • 59.布局控制器view中的子控件位置和尺寸的代码最好放到viewDidLayoutSubviews方法中,因为控制器的view有可能是通过xib、代码、storyboard创建,所以一开始初始化时的尺寸是不准确的。但是当view布局完成后的尺寸是最准确的

  • 60.Xcode中蓝色文件夹表示在项目中真实存在

  • 61.ABS()是取绝对值函数

  • 62.- (void)prepareLayout用来做布局的初始化操作(不建议在 init 方法中进行布局的初始化操作)

  • 63.- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error;这个方法获取文件大小是可靠的,文件计算不准确

《百思不得姐》项目知识点总结相关推荐

  1. Java牛客网社区项目——知识点面试题

    Java牛客网社区项目--知识点&面试题 持续更新中(ง •̀_•́)ง 文章目录 Java牛客网社区项目--知识点&面试题 请简要介绍一下你的项目? 什么是Spring框架? 对Sp ...

  2. 优达学城java_优达学城数据分析师纳米学位——P4项目知识点整理及代码分析

    #P4项目知识点整理 ##P4项目概述 ##R语言知识点汇总 ##数据分析实例解析 #P4项目概述 使用R+EDA(exploratory data analysis探索性数据分析)(探索式数据分析是 ...

  3. python Web项目知识点分析

    django项目知识点分析 1.异步任务celery和中间人rabbitmq ​ 1.1 celery提供异步任务,遇到耗时操作的任务都可以交给celery来完成 ​ 1.2 通信过程是,生产者(任务 ...

  4. 探花交友项目知识点总结

    探花交友项目知识点 1.父组件向子组件添加内容,可以理解为vue中的插槽 在子组件中可以通过{props.children}来进行接收父组件向子组件标签中添加的内容 2.样式的布局技巧,要是中间和左边 ...

  5. 关于电影推荐项目知识点

    关于电影推荐项目知识点 目录 关于电影推荐项目知识点 一.常用推荐算法分类 1.基于人口统计学的推荐 2.基于内容的推荐 3.基于协同过滤的推荐 二.模型求解算法---ALS 三.项目整体架构流程图 ...

  6. 智能营销文本生成项目知识点总结

    最近业余时间弄了一个文本生成的项目,在此将相关知识点总一下总结. 项目说明 本项目中,我们作为输入的原文称之为 source,待生成的目标文本 称之为 target ,用来作为 target 好坏的参 ...

  7. 百思不得姐项目(第一天)

    打算写一个项目用于整合自己学习的知识,挑了一下,打算模仿写一个"百思不得姐" 用博客来记录一下这个项目遇到的问题和一些思路吧!也不知道多少天能做完. 今天是第一天,先做点准备工作! ...

  8. iOS下拉九宫格、百思不得姐项目、微信对话框等源码

    iOS精选源码 自定义中心按钮的TabBar,按钮凸出部分点击有效,高度随意设 仿微信提醒对话框 隐私权限API,用于做更友好的权限访问 想要更简单的推送消息,看本文就对了 WKWebView实现js ...

  9. iOS下拉九宫格、百思不得姐项目、微信对话框等源码 1

    iOS精选源码 自定义中心按钮的TabBar,按钮凸出部分点击有效,高度随意设 仿微信提醒对话框 隐私权限API,用于做更友好的权限访问 想要更简单的推送消息,看本文就对了 WKWebView实现js ...

最新文章

  1. 白嫖一时爽!一直白嫖一直爽!程序员必备神器!
  2. 风险度量之[下行风险]
  3. 【Android游戏开发十七】让玩家自定义手势玩转Android游戏!
  4. 交换机VLAN划分详细手册
  5. LeetCode面试刷题技巧-二分查找算法(下):通过 LeetCode 学习二分查找算法-销售价值减少的颜色球
  6. 阿里P7架构师谈职业生涯规划,给遇到瓶颈,迷茫期的人群一些建议
  7. SAP Spartacus 的 Above-the-Fold Loading 加载机制
  8. php如何禁用浏览器的缓存,php如何禁止浏览器使用缓存页面
  9. crc算法java_c语言的crc16算法转java
  10. 高性能MySQL—第一章 MySQL架构与历史
  11. 计算机科学与软件工程的区别
  12. Bootstrap 面包屑导航
  13. 如何计算虚拟化vcpu_首次公开:腾讯云虚拟化技术原理及可用性提升实践
  14. svn删除所有unversioned文件
  15. 微信小程序icon图标怎么用
  16. 药物不良反应数据库信息的下载
  17. 基于MATLAB图像处理的自动QQ小游戏(一)自动扫雷篇
  18. 如何制作一本《现代Javascript教程》电子书离线学习使用
  19. 简信CRM:CRM科学服务体系,促进企业销售增长
  20. LuaXposed:使用Lua编写Xposed模块

热门文章

  1. 《Adobe Flash CS6中文版经典教程》——1.10 修改内容和舞台
  2. 通用方法 windows下安装Git +Gerrit环境以及配置提交日志模板
  3. C#获取本机IP地址的4种方式
  4. R语言ggplot2可视化:使用geom_rect函数在指定的位置添加自定义颜色的方框突出(hightlight)特定区域内的数据内容(transparent window/keyhole)
  5. java打印代码执行耗时
  6. 语音识别入门 --各个模型的整理
  7. java毕业设计读书网络社区设计Mybatis+系统+数据库+调试部署
  8. 恒温恒湿实验室(房)建设、设计SICOLAB
  9. PS如何快速还原与恢复图片?
  10. C#实现力扣双周赛算法题:以组为单位订音乐会的门票订购