ios开发中的问题

2017-12-19  本文已影响17人  Vijay_

拉伸图片

在图片的宽度/高度不够导致拉伸难看时可以在 Assets中点击图片右侧的Silcing设置图片拉伸方向

拉伸图片

CocoaPods

事件响应

按钮设置文字和图片

必须分状态设置,否则设置无效!

[btn setTitle:@"" forState:UIControlStateNormal];

[btn image:image forState:UIControlStateNormal];

[btn setTitleColor:$color forState:UIControlStateNormal];

tableFooterView异步获取高度,重新计算

//因为footerView的高度是通过网络获取到的数据计算的
//所以在设置tableView的footer时,它是没有高度的
//于是tableView的contentSize会忽略它,导致等footerView有了高度还是无法上下滚动
VJFooterView* footerView = [[VJFooterView alloc] init];
    footerView.backgroundColor = [UIColor whiteColor];
    self.tableView.tableFooterView = footerView;
//在计算出高度后,让父控件(tableView)重新计算内容高度.
self.vj_height = squareList.count / 4 * buttonH;
    
    UITableView *tableView =  (UITableView*)self.superview;
    [tableView reloadData];

常见查找字符串方法

//是否以http开头
[model.url hasPrefix:@"http"]
//是否以http结尾
[model.url hasSuffix:@"http"]
//是否包含http
[model.url containsString:@"http"]
//查找到http的起始角标和长度(为0则没找到)
NSRange range =  [model.url rangeOfString:@"http"];
    range.location;
    range.length;

从View控件中拿到当前控制器

//拿到当前view所在的窗口的跟控制器
UITabBarController *tbVC =  (UITabBarController *)self.window.rootViewController;
//拿到跟控制器(tabbarcontroller)中当前选中的控制器
        UINavigationController *navigation =  tbVC.selectedViewController;
        VJWebViewViewController* webVC = [[VJWebViewViewController alloc] init];
        webVC.url = model.url;
        webVC.title = model.name;
        [navigation pushViewController:webVC animated:YES];

获取文件夹信息

NSString* path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"default"];
    NSFileManager* mgr = [NSFileManager defaultManager];
    NSDictionary* attr = [mgr attributesOfItemAtPath:path error:nil];
    NSLog(@"%@",attr);
    
    //创建时间
    NSFileCreationDate = "2017-12-16 08:30:44 +0000";
    //文件扩展名是否隐藏
    NSFileExtensionHidden = 0;
    NSFileGroupOwnerAccountID = 20;
    NSFileGroupOwnerAccountName = staff;
    //修改日期
    NSFileModificationDate = "2017-12-16 08:30:44 +0000";
    NSFileOwnerAccountID = 501;
    NSFilePosixPermissions = 493;
    NSFileReferenceCount = 3;
    //文件大小(注意,要知道文件夹里所有文件的大小必须要遍历计算)
    NSFileSize = 96;
    NSFileSystemFileNumber = 8591546449;
    NSFileSystemNumber = 16777220;
    //文件类型 (文件夹还是文件)    
    NSFileType = NSFileTypeDirectory;

获取某个文件下所有文件的大小

    unsigned long long allFileSize = 0;
    NSString* path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"default/com.hackemist.SDWebImageCache.default/2a887a10f755aa623ce2ea0dad4822a2.jpg"];
    NSFileManager* mgr = [NSFileManager defaultManager];

//    NSArray* files = [mgr contentsOfDirectoryAtPath:path error:nil];
//    当前文件夹和所有子文件夹孙文件夹一直到最底层的所有文件名称
    NSArray<NSString*>* allFiles = [mgr subpathsAtPath:path];
    for (int i =0; i<allFiles.count; i++) {
        NSString* filePath =  [path stringByAppendingPathComponent:allFiles[i]];
        NSDictionary *dic = [mgr attributesOfItemAtPath:filePath error:nil];
        //字典默认有个属性叫fileSize 对应的就是取出NSFileSize建对应的值
        //等同于 dic[@"NSFileSize"]
        allFileSize+=dic.fileSize;
    }
    

异步线程计算文件

//    设置还没计算完文件时的样式
//    创建一个指示器(加载)视图作为单元格右边视图
    UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [loadingView startAnimating];
    cell.accessoryView = loadingView;
    cell.textLabel.attributedText = [[NSAttributedString alloc] initWithString:@"清除缓存" attributes:@{NSForegroundColorAttributeName:[UIColor purpleColor]}];
//    在子线程计算文件大小 防止卡死
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
//        获取需要计算的文件路径
//        NSString* path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"default"];
        NSString* path = @"/Users/jiewang/Documents";
//        拼接文字
        NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"清除缓存(%.2fMB)",path.fileSize/1000.0/1000.0] attributes:@{NSForegroundColorAttributeName:VJRandomColor}];
//        回到主线程更改文字
        dispatch_async(dispatch_get_main_queue(), ^{
            
            cell.textLabel.attributedText = attrString;
//            清空指示器视图
            cell.accessoryView = nil;
//            改为箭头
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        });
        
    });

注册重用Cell

static NSString * const tableCellId = @"clearCell";

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView registerClass:[VJClearCellTableViewCell class] forCellReuseIdentifier:tableCellId];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //上面已经使用register注册好了该标识对应的cell类 
    //如果这里取不到缓存的Cell则会用上面注册的cell来创建
    //可以直接在cell类中重写initWithStyle方法初始化
    VJClearCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableCellId];
    return cell;
}

清除SDWebImage以及自定义的缓存

    #import <SDImageCache.h>
    
    
    //清除SDImage的缓存后,清除自己文件
    [[SDImageCache sharedImageCache] clearDiskOnCompletion:^(){
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSFileManager *mgr = [NSFileManager defaultManager];
            [mgr removeItemAtPath:CustomCacheDir error:nil];
            /**
             第一个参数是要创建的文件夹路径,
             第二个是"如果文件夹路径前面的路径不存在是否补全"
             第三个是文件夹属性
             */
            [mgr createDirectoryAtPath:CustomCacheDir withIntermediateDirectories:YES attributes:nil error:nil];
            dispatch_async(dispatch_get_main_queue(), ^{
                [SVProgressHUD showSuccessWithStatus:@"清除成功"];
                [SVProgressHUD dismissWithDelay:2];
            });
        });
    }];

    

NSFileManger常用清除缓存方法

    NSFileManager *mgr = [NSFileManager defaultManager];
//            获取文件属性的字典>包含文件类型(文件是文件夹还是文件)以及文件大小
    [mgr attributesOfItemAtPath:$filePath error:nil];
//            获取指定路径下的所有子孙等文件名的迭代器(可以使用for in循环)
    [mgr enumeratorAtPath:$filePath];
//            获取指定路径下的所有子孙等文件名的数组
    [mgr subpathsAtPath:$filePath];
//            返回该路径是否存在并修改bool指针为是否该路径为文件夹
    [mgr fileExistsAtPath:$filePath isDirectory:$Bool];
//            删除指定文件夹(文件)
    [mgr removeItemAtPath:$filePath error:nil];
    /**
     第一个参数是要创建的文件夹路径,
     第二个是"如果文件夹路径前面的路径不存在是否补全"
     第三个是文件夹属性
     */
    [mgr createDirectoryAtPath:$filePath withIntermediateDirectories:YES attributes:$fileAttrDictionary error:nil];

TableView循环利用注册多个Cell

//由于有些特定的cell里封装了不同的逻辑,所以不能与普通的cell循环利用,这时需要注册多个Cell
static NSString * const tableCellId = @"clearCell";
static NSString * const tableCellSettingId = @"settingCell";

//注册两个不同的cell 在clearCell中封装了与SettingCell不同的逻辑
//所以下面在获取settingCell时需要排除是clearCell的情况,反之亦然

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView registerClass:[VJClearCellTableViewCell class] forCellReuseIdentifier:tableCellId];
    [self.tableView registerClass:[VJSettingCell class] forCellReuseIdentifier:tableCellSettingId];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 0 ) {
        return [tableView dequeueReusableCellWithIdentifier:tableCellId];
    }else{
        VJSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:tableCellSettingId];
        cell.textLabel.text = [NSString stringWithFormat:@"%zd",indexPath.row];
        return cell;
    }
}

关于子线程执行block强引用self延迟销毁

解决方法

//使用弱指针执行当前对象,则block中强引用的是该弱指针对象,
//弱指针不会强引用当前对象所以不会妨碍销毁,并且当对象销毁时会指向nil.
//typeof($obj)是获取$obj的类型
__weak typeof(self) weakSelf = self;

如果不希望UIButton点击颜色变浅

需要自定义一个button并且重写父类的setHighlighted方法,就不会出现高亮状态

计算一段文字高度宽度

//计算UIButton的文字尺寸,
//注意:仅仅适用于单行文字,多行文字需要使用boundingRectWithSize
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
NSString *title = [btn titleForState:UIControlStateNormal];
CGSize titleSize = [title sizeWithAttributes:@{NSFontAttributeName:titleBtn.titleLabel.font}];

多行文字高度计算

NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading一定要加这两个枚举值,否则无效

计算高度最好字体设置大1像素 比如字体是13的话 计算就写14,因为还有行高,否则计算不准确

boundingRectWithSize:maxBound 
options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading 
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13]} 
context:nil

关于滚动视图和控制器的自动设置位置

contentInset(内边距)和bounds.origin是一样作用

bounds是视图内部尺寸大小bounds的origin相当于contentInset,根据内容所在的位置进行上下从而显示出了滚动的效果,内容视图的坐标系是相对自身的

scrollView的滚动就是监听一个手指滑动事件然后移动bounds.origin来上下左右的显示内容

当设置了scrollView的contentInset最好也设置一下它的滚动条内边距
vc.tableView.scrollIndicatorInsets = vc.tableView.contentInset;

bounds.size则是内容的范围,显示区域,默认与frame.size相等

可以把bounds想象成一个矩形块,它的地下是所有的内容(所有的子控件),它在上面通过bounds.origin移动来显示范围内的东西

//示例代码,把控件加到超出视图然后隐藏超出视图的东西。
UIView* uv = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    UISwitch *sv = [[UISwitch alloc] initWithFrame:CGRectMake(120, 120, 0, 0)];
    uv.backgroundColor = VJRandomColor;
//修改视图的bounds的坐标,移动到子控件所在的位置,将其显示出来,
//注意:坐标是相对视图本身的,所以看不出来移动
    uv.bounds = CGRectMake(100, 100, 100, 100);
    [uv addSubview:sv];
    uv.clipsToBounds = YES;
    [self.view addSubview:uv];

结果

结果

viewWithTag相关

快速遍历数组执行方法

xib子类是不会继承父类的样式的

设置UIButton文字和图片间距

修改自定义tableViewCell

由于tableview会自动计算尺寸,所以在控制器里设置高度都无效,需要在自定义的类中重写setFrame方法,因为不管哪个方法修改cell的尺寸 最后都要进入setFrame方法中,直接在里面重写即可。

- (void)setFrame:(CGRect)frame{
     frame.origin.y += 10;
    frame.size.height -= 10;
    [super setFrame:frame];
}

自定义tableViewCell

tableView的顶部刷新指示器

把字符串转换成NSDate并获取时分秒

一般情况下 NSCalendar 和NSDate NSDateFormatter是一起用的
NSCalendar用来处理NSDate,NSDateFormatter用来转换Date和string

比较日期差值使用NSCalender的components:xxx fromDate:xxx toDate:xxx
获取差值日期对象,可以直接获取到相差几天几小时几秒(会自动进位很方便)

//    获取当前系统日历对象
    NSCalendar * calendar = [NSCalendar currentCalendar];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//    转换日期格式必须与返回的格式相同 否则不能把字符串转换成date(会返回nil)
    formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
//    把字符串转换成NSDate
    NSDate *createDate = [formatter dateFromString:topic.created_at];
    if (createDate) {
        // 获取从帖子发布到现在的差值日期对象
        NSDateComponents * components = [calendar components:NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:createDate toDate:[NSDate date] options:kNilOptions];
        
        NSInteger diffDay = components.day;
        NSInteger diffhour = components.hour;
        NSInteger diffminute = components.minute;
        //        超过一天
        if (diffDay>0) {
            self.createdAtLabel.text = [NSString stringWithFormat:@"%li天前",components.day];
        }else if (diffhour>0){
            self.createdAtLabel.text = [NSString stringWithFormat:@"%li小时前",components.hour];
        }else if (diffminute>0){
            self.createdAtLabel.text = [NSString stringWithFormat:@"%li分钟前",components.minute];
        }
        
    }

    

继承,实现协议,分类(类别),类拓展

//.h文件
xxx:superClass 继承
xxx:superClass<xxxprotocol> 实现协议
//.m文件
xxx() 类拓展
xxx(xxx) 分类

在xib中设置图片和按钮大小

关于tableViewCell循环利用

从xib中加载的view设置尺寸显示不正确

NSInteger占两位,空值0代替

父类子类通信

手势事件获取的缩放或者平移都可以转换成CGATransform使用在控件上

上一篇下一篇

猜你喜欢

热点阅读