• iOS工作笔记(十五)


    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 > 0) {
                [_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:5], [NSNumber numberWithInt:5], nil]];
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, lineView.frame.size.width, 0);
    [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":@"15",@"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:@"15"]) {
                *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"];
            }
        }];
    }
  • 相关阅读:
    金融培训心得:银行客户经理10大不专业表现
    团队中的八类乞丐:你不改变,谁也救不了你!
    笔记本分类大全
    拆轮子 笔记
    spacemacs 自定义配置 笔记
    Fedora 25 安装搜狗输入法
    spark 配置使用
    Anaconda 仓库的镜像
    vscode vim配置
    使用Vim normal 命令 修改可视块区域
  • 原文地址:https://www.cnblogs.com/Apologize/p/6097223.html
Copyright © 2020-2023  润新知