1.使用MJRefresh上拉加载的小细节

MJRefreshBackGifFooter *footer = [MJRefreshBackGifFooter footerWithRefreshingBlock:^{
[_searchResultView.mj_footer endRefreshing];
//加载新内容
[self loadMoreItemList];
}];

这样写的效果是,当下拉加载时,新内容是不直接展现的,还得继续往上拉,才能看到新内容

当换种写法,将endRefreshing写在loadMoreItemList时,效果就不一样了

MJRefreshBackGifFooter *footer = [MJRefreshBackGifFooter footerWithRefreshingBlock:^{
//加载新内容
[self loadMoreItemList];
}]; -(void)loadMoreItemList{
//其余代码…… //停止刷新
if (_searchResultView.mj_footer.state == MJRefreshStateRefreshing) {
if (arrTemp.count > ) {
[_searchResultView.mj_footer endRefreshing];
} else {
[_searchResultView.mj_footer endRefreshingWithNoMoreData];
}
}
}

这样效果就好多了,出现新内容直接展示,而不需要在往上拖才知道有新内容,体验比较好。

虽然是细节问题,但体验会不一样。

2.画贝塞尔曲线时,以下的两种画法区别在于

UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:view.bounds];

bezierPathWithRect     根据一个矩形画曲线
bezierPathWithOvalInRect      根据一个矩形的内切圆画曲线

3.若有需求,在app中,一个界面只在用户每天首次启动时展示,那么思路可以这样,先获取当前时间,然后与NSUserDefaults中存储的时间相比较,若为同一天,则不展示,反之亦然。

NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
NSString *timeStorage = [user objectForKey:@"signTime"]; NSDate *senddate = [NSDate date];
NSDateFormatter *dateformatter = [[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"YYYY-MM-dd"];
NSString *timeNow = [dateformatter stringFromDate:senddate];
if (![timeNow isEqualToString:timeStorage]) {
//说明是当天首次启动
}

上述方法有点问题,若牵涉到多账号问题,如换个账号登录,那么第二个账号就算当天首次登录,也不会展示。

解决方法就是往NSUserDefaults存储时间时,key把例子中的signTime变为用户id即可。

4.画虚线,可以用drawRect,也可以用CAShapeLayer,相对来说,后者的使用范围更广一些,既可以写在view内,也可以写到controller中。

以CAShapeLayer为例,需要用到setLineDashPattern设置虚线线宽和间距

CAShapeLayer *shapeLayer = [CAShapeLayer layer];
[shapeLayer setBounds:lineView.bounds];
[shapeLayer setPosition:CGPointMake(lineView.frame.size.width / 2.0, lineView.frame.size.height)];
[shapeLayer setFillColor:[UIColor clearColor].CGColor];
//设置虚线颜色
[shapeLayer setStrokeColor:[UIColor lightGrayColor].CGColor];
//设置虚线宽度
[shapeLayer setLineWidth:lineView.frame.size.height];
//设置虚线的线宽及间距
[shapeLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:], [NSNumber numberWithInt:], nil]];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, , );
CGPathAddLineToPoint(path, NULL, lineView.frame.size.width, );
[shapeLayer setPath:path];
CGPathRelease(path);
[lineView.layer addSublayer:shapeLayer];

效果如下:

5.底部导航栏tabbar的点击代理方法中,点击的序号可以获取上一个和现在点击的

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController*)viewController {
//现在点击的
NSUInteger selectedNum = [tabBarController.viewControllers indexOfObject:viewController];
//上一个
NSUInteger selectedIndex = tabBarController.selectedIndex;
}

6.获取屏幕可视区域上有哪些cell显示,可以用

①UITableview的方法,这个最直接,返回一个UITableviewcell的数组。

- (NSArray*)visibleCells;

②UITableview的又一个方法,返回一个NSIndexPath的数组,可以直接用indexpath.row去调table里的数据了。比较方便用于自定制的cell

- (NSArray*)indexPathsForVisibleRows;

③获取index内的frame

- (CGRect)rectForRowAtIndexPath:(NSIndexPath*)indexPath;

7.判断controller是否在当前屏幕展示,即出现在可视区域,在controller中可以用

self.isViewLoaded && self.view.window来判断。
也可以添加到controller的分类中

+(BOOL)isControllerVisible:(UIViewController *)controller{
return[controller.isViewLoaded && controller.view.window];
}

因为当controller的view展示时,view.window一定不是空值。

8.NSArray和NSDictionary的遍历,除了用for外,还可以用block遍历

- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ObjectType obj, BOOL *stop))block;

并且遍历时的option可以用NSEnumerationReverse(反向遍历)和NSEnumerationConcurrent(并发遍历),其中并发遍历由系统自己决定线程和资源消耗,比较高效。这两个参数也可以同时使用。

self.numArr = @[@"Fuck",@"You",@"Hello",@"World",@"What",@"Are",@"You",@"Doing",@"XXX",@"Hallery"];
self.numDict = @{@"name":@"Tom",@"age":@"",@"gender":@"male"}; -(void)testRecycle{
[self.numArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *tempA = obj;
NSLog(@"---%@",tempA);
if ([tempA isEqualToString:@"Hallery"]) {
*stop = YES;
}
}]; [self.numDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString *tempA = obj;
NSLog(@"+++%@",tempA);
if ([tempA isEqualToString:@""]) {
*stop = YES;
}
}];
} /**
遍历时改变元素内容,利用并发执行
*/
-(void)changeObjWhenEnumerate{
NSArray *tempArr = self.numArr;
NSMutableArray *arrChange = [NSMutableArray arrayWithArray:tempArr];
//NSEnumerationConcurrent并发遍历
[arrChange enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *locationStr = obj;
if ([locationStr isEqualToString:@"Are"]) {
[arrChange removeObject:@"Are"];
}
}];
}

iOS工作笔记(十五)的更多相关文章

  1. iOS工作笔记(十四)

    1.scrollview的frame指的是其可视范围,contentSize指的是其滚动范围,分别是在水平方向和竖直方向上的 所以要让scrollview在水平方向不能滚动,那么需要如下设置 _scr ...

  2. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  3. How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘

    个人总结:读完这篇文章需要15分钟,文章主要讲解了Babel和TypeScript的工作原理,(例如对es6 类的转换,是将原始es6代码转换为es5代码,这些代码中包含着类似于 _classCall ...

  4. (C/C++学习笔记) 十五. 构造数据类型

    十五. 构造数据类型 ● 构造数据类型概念 Structured data types 构造数据类型 结构体(structure), 联合体/共用体 (union), 枚举类型(enumeration ...

  5. (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)

    一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的 ...

  6. MySQL学习笔记十五:优化(2)

    一.数据库性能评测关键指标 1.IOPS:每秒处理的IO请求次数,这跟磁盘硬件相关,DBA不能左右,但推荐使用SSD. 2.QPS:每秒查询次数,可以使用show status或mysqladmin ...

  7. iOS工作笔记(十三)

    1.automaticallyAdjustsScrollViewInsets的使用 这是UIViewController的属性,设置为YES就是根据status bar,navigation bar, ...

  8. 从零开始学ios开发(十五):Navigation Controllers and Table Views(中)

    这篇内容我们继续上一篇的例子接着做下去,为其再添加3个table view的例子,有了之前的基础,学习下面的例子会变得很简单,很多东西都是举一反三,稍稍有些不同的内容,好了,闲话少说,开始这次的学习. ...

  9. 论文阅读笔记十五:Pyramid Scene Parsing Network(CVPR2016)

    论文源址:https://arxiv.org/pdf/1612.01105.pdf tensorflow代码:https://github.com/hellochick/PSPNet-tensorfl ...

随机推荐

  1. Win7下安装Centos7

    win7下安装Centos同一块硬盘时:win启动项没有,使用pe进行修复,之后用easybcd进行centos启动项修复,grub2,自动搜索两块硬盘时:不要动启动项,bios选启动的硬盘即可 li ...

  2. jquery用append添加按钮之后,按钮监听无法使用的解决方法

    <!DOCTYPE html><html><head><meta charset="utf-8"> <title>< ...

  3. 扩展easyui.datagrid,添加数据loading遮罩效果代码 --来自网摘收集

    //jquery.datagrid 扩展 (function (){ $.extend($.fn.datagrid.methods, { //显示遮罩 loading: function(jq){ r ...

  4. cs11_c++_lab6

    expressions.hh #ifndef EXPRESSIONS_HH #define EXPRESSIONS_HH #include "environment.hh" #in ...

  5. 将对象的所有属性名放到一个数组中 || 获得对象的所有属性名 || return;不具有原子性 || 怎样自己制作异常|| 判断对象有没有某个属性 || 当传递的参数比需要的参数少的时候,没有的值会被赋予undefined || 获得函数实际传递的参数 || 怎么用函数处理一个对象 || 用一个名字空间定义一个模块所有的函数 || 给一个对象添加方法

    获得对象的所有属性名 || 将对象o的所有属性名放到数组中 var o = {x:1,y:2,z:3}; var arr = []; var i = 0; for(arr[i++] in o){};/ ...

  6. 父进程等待子进程结束 waitpid wait

    我们一直在强调一个概念就是进程是一个程序执行的实例,是内核在虚拟概念下创建的实体,它实例化的体现在用户态就是程序代码和代码使用的变量(存储空间),在内核态就是内核为我们每个进程所保存的数据结构(状态信 ...

  7. GetStoredProcCommand和GetSqlStringCommand的区别

    原文:http://www.ithao123.cn/content-4004602.html http://hi.baidu.com/847270942/blog/item/c224dd557ff74 ...

  8. ---Linux 10 年的硕果累累啊!

    http://mt.sohu.com/20160128/n436204298.shtml

  9. LR常用函数以及调用自定义函数

    2.LR常用函数以及调用自定义函数 2.1.LR常用函数以及对信息的判断 2.1.1. LR内部自定义函数 在LR脚本中定义变量和编写自定义函数,需将变量的声明放在脚本其他内容的上方,否则会提示[il ...

  10. SQL Server 常用函数介绍

    --聚合函数 count( * | 字段名) --统计数据表中的数据总数sum( 表达式 | 字段名) --计算表达式或字段名中数据的和,表达式或字段名的数据类型要求是数值型avg( 表达式 | 字段 ...