iOS学习

iOS常用方法工具箱(1)

2022-07-05  本文已影响0人  吴泽方

在iOS开发中经常会用上的一些方法工具,今天做了下整理,后续会陆续更新,欢迎互相加好友交流, 620软件 http://www.620rj.com

常用方法太多了,合并在一个代码块里面吧,

///获取项目本身的版本号,返回2.5.8
+ (NSString *)getCurrentVer2 {
    NSDictionary *sysDic = [[NSBundle mainBundle] infoDictionary];
    NSString *ver = [NSString stringWithFormat:@"%@",[sysDic objectForKey:@"CFBundleShortVersionString"]];
    return ver;
}

///判断iOS系统版本
+ (double)systemVersion {
    NSString *version = [UIDevice currentDevice].systemVersion;
    return version.doubleValue;
}

///过滤表情符(仅保留汉字、字母、数字、符号)
+ (NSString *)delIllegalString:(NSString *)string {
    if (string.length == 0) {
        return @"";
    }
    
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]"options:NSRegularExpressionCaseInsensitive error:nil];
    
    string = [regex stringByReplacingMatchesInString:string
                                             options:0
                                               range:NSMakeRange(0, [string length])
                                        withTemplate:@""];
    return string;
}

///颜色转UIImage
+(UIImage*) createImageWithColor:(UIColor *) color {
    CGRect rect=CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return theImage;
}

///震动一下 点击按钮调用增加触感体验
+ (void) touchVibration {
    if (@available(iOS 11.0, *)) {
        UIImpactFeedbackGenerator *feedBackGenertor = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
        [feedBackGenertor impactOccurred];
    } else {
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    }
}

///完整打印处理json,有时xcode控制台打印长json 会不见了一部分,用这个方法可以完整打印
+ (void)printFormatting:(NSDictionary *)dic {
    if (LogSwitch == 0) {
        NSData *data = [NSJSONSerialization dataWithJSONObject:dic
                                                       options:NSJSONWritingPrettyPrinted
                                                         error:nil];
        NSString *str =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        printf("请求返回\n%s\n------------------------------------------------------------------------------------------------\n\n\n ",[str UTF8String]);
    }
}

///生成13位时间戳
+ (NSString *)getNowTimeTimestamp2 {
    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval a=[dat timeIntervalSince1970];
    //转为字符型需要乘以1000,否则是10位,但java返回的时间戳是13位
    NSString*timeString = [NSString stringWithFormat:@"%0.f", a*1000];
    return timeString;
}

///生成10位时间戳
+ (NSString *)getNowTimeTimestamp10position {
    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval a=[dat timeIntervalSince1970];
    NSString*timeString = [NSString stringWithFormat:@"%0.f", a];
    return timeString;
}

/**

 G:      公元时代,例如AD公元
 yy:     年的后2位
 yyyy:   完整年
 MM:     月,显示为1-12,带前置0
 MMM:    月,显示为英文月份简写,如 Jan
 MMMM:   月,显示为英文月份全称,如 Janualy
 dd:     日,2位数表示,如02
 d:      日,1-2位显示,如2,无前置0
 EEE:    简写星期几,如Sun
 EEEE:   全写星期几,如Sunday
 aa:     上下午,AM/PM
 H:      时,24小时制,0-23
 HH:     时,24小时制,带前置0
 h:      时,12小时制,无前置0
 hh:     时,12小时制,带前置0
 m:      分,1-2位
 mm:     分,2位,带前置0
 s:      秒,1-2位
 ss:     秒,2位,带前置0
 S:      毫秒
 Z:      GMT(时区)
 */

///将时间戳转为时间字符串(timeString为13位的时间戳)
+ (NSString *)timestampTOtimeString:(NSString *)timeString {
    if (timeString.length == 0 || [timeString isEqualToString:@""]) {
        NSLog(@"数据异常 %s",__func__);
        return @"";
    }
  
    ///如果非13位的时间戳,这里不要除以1000.0
    NSTimeInterval interval = [timeString doubleValue];
    if (timeString.length == 13) {
        interval = [timeString doubleValue] / 1000.0;
      }
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy年MM月dd日H时m分"];
    NSString *dateString = [formatter stringFromDate: date];
    return dateString;
}

///抖动效果
+ (void)loadShakeAnimationForView:(UIView *)view {
    CALayer *lbl = [view layer];
    CGPoint posLbl = [lbl position];
    CGPoint y = CGPointMake(posLbl.x-10, posLbl.y);
    CGPoint x = CGPointMake(posLbl.x+10, posLbl.y);
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setTimingFunction:[CAMediaTimingFunction
                                  functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [animation setFromValue:[NSValue valueWithCGPoint:x]];
    [animation setToValue:[NSValue valueWithCGPoint:y]];
    [animation setAutoreverses:YES];
    [animation setDuration:0.08];
    [animation setRepeatCount:3];
    [lbl addAnimation:animation forKey:nil];
}

/**
 * @method
 *
 * @brief 获取两个日期之间相隔的天数或月数
 * @param fromDate       起始日期
 * @param toDate         终止日期
 * @return    总天数
 */
+ (NSInteger)numberOfDaysWithFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //月数- NSCalendarUnitMonth
    //天数- NSCalendarUnitDay
    NSDateComponents  *comp = [calendar components:NSCalendarUnitDay
                                          fromDate:fromDate
                                            toDate:toDate
                                           options:NSCalendarWrapComponents];
    //comp.day  返回天数
    //comp.month 返回月数
    return comp.day;
}

/**
 * @method
 *
 * @brief 获取两个日期之间相隔的天数或月数
 * @param fromDate       起始日期
 * @param toDate         终止日期
 * @return    总天数
 */
+ (NSInteger)numberOfMonthWithFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    //月数- NSCalendarUnitMonth
    //天数- NSCalendarUnitDay
    NSDateComponents *comp = [calendar components:NSCalendarUnitMonth
                                         fromDate:fromDate
                                           toDate:toDate
                                          options:NSCalendarWrapComponents];
    //comp.day  返回天数
    //comp.month 返回月数
    return comp.month;
}

跳转到当前app的权限设置页面

///跳转到当前app的权限设置页面
+ (void)pushSysAPPsetingVC {
    if ([[self class] systemVersion] > 10.0) {
        NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication]openURL:url options:@{} completionHandler:^(BOOL success) {
        }]; //iOS 10以后的方法
    }
}

四边阴影效果

///view添加四边阴影效果
+ (void)addShadowToView:(UIView *)theView withColor:(UIColor *)theColor {
    //阴影颜色
    theView.layer.shadowColor = theColor.CGColor;
    //阴影偏移,默认(0, -3)
    theView.layer.shadowOffset = CGSizeMake(0,-3);
    //阴影透明度,默认0
    theView.layer.shadowOpacity = 0.8;
    //阴影半径,默认3
    theView.layer.shadowRadius = 5;
    //设置masksToBounds,否则不会显示阴影
    theView.layer.masksToBounds = NO;
}

保留小数点后1位 ,可以举一反三保留N位小数点

///保留小数点后1位,如:0.85、2.86 均返回:0.8、2.8
+ (NSString *)getTheCorrectNum_1:(NSString *)tempString {
    ///计算截取的长度
    NSUInteger endLength = tempString.length;
    ///判断字符串是否包含.
    if ([tempString containsString:@"."]) {
        ///取得.的位置
        NSRange pointRange = [tempString rangeOfString:@"."];
        NSLog(@" ---->%lu %s",pointRange.location,__func__);
        
        ///判断.后面有几位
        NSUInteger f = tempString.length - 1 - pointRange.location;
        
        ///如果大于2位就截取字符串保留1位,如果小于两位,直接截取
        if (f >= 2) {
            endLength = pointRange.location + 2;
        }
    }
    
    ///先将tempString转换成char型数组
    NSUInteger start = 0;
    const char *tempChar = [tempString UTF8String];
    ///遍历,去除取得第一位不是0的位置
    for (int i = 0; i < tempString.length; i++) {
        if (tempChar[i] == '0') {
            start++;
        } else {
            break;
        }
    }
    ///根据最终的开始位置,计算长度,并截取
    NSRange range = {start,endLength-start};
    tempString = [tempString substringWithRange:range];
    return tempString;
}

从工程json文件读取数据返回字典

/**
从工程json文件读取数据返回字典,
name:文件名 tpyes:后缀名称, 如:test.txt 注意该文件内容必须是标准json结构数据
*/
+ (NSDictionary *)readLocalJsonFor:(NSString *)names andType:(NSString *)types {
    NSDictionary *dic = [NSDictionary dictionary];
    if (names.length != 0 || types.length != 0) {
        NSString *imagePath = [[NSBundle mainBundle] pathForResource:names ofType:types];
        NSString *string = [[NSString alloc] initWithContentsOfFile:imagePath encoding:NSUTF8StringEncoding error:nil];
        NSData *resData = [[NSData alloc]initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]];
        dic = [NSJSONSerialization JSONObjectWithData:resData options:NSJSONReadingMutableLeaves error:nil];
    }
    return dic;
}

字符串分割

/**
 将字符串按从左取2位一组切割分为多组  type:为分割符,如逗号、空格等
 案例:
 传入: 123   分隔符为逗号    则返回:12,3
 传入: 1234   分隔符为逗号    则返回:12,34
 传入: 12345   分隔符为逗号    则返回:12,34,5
 传入: 1   分隔符为逗号    则返回:1,
 */
+ (NSString *)stringCutout:(NSString *)str cutOutTypeStr:(NSString *)type {
    NSMutableArray *dataArrs = [NSMutableArray arrayWithCapacity:0];
    NSInteger tmp = str.length/2;
    for (int i = 0; i < str.length+1; i++) {
        if (i%2 == 0 & i != 0) {
            [dataArrs addObject:[NSString stringWithFormat:@"%@",[str substringWithRange:NSMakeRange(i-2,2)]]];
        }
        
        if (tmp*2 == i) {
            [dataArrs addObject:[NSString stringWithFormat:@"%@",[str substringWithRange:NSMakeRange(tmp*2,str.length-tmp*2)]]];
        }
    }
    return [dataArrs componentsJoinedByString:type];
}

在Documents内创建文件夹

///在Documents内创建文件夹
+ (BOOL)createDocumentsFolderName:(NSString *)folderName {
    if (folderName.length == 0) {
        return NO;
    }
    ///获取Documents文件夹路径
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    ///要建立的文件夹名称
    NSString *filePath = [documentsPath stringByAppendingPathComponent:folderName];
    BOOL isYES;
    BOOL exit = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isYES];
    if (isYES || !exit) {
        if ([[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil]) {
            return YES;
        } else {
            return NO;
        }
    }
    return NO;
}

获取手机沙盒路径

///获取手机沙盒路径 types:0获取Documents  1获取tmp
+ (NSString *)getSystemSandboxPathFor:(int)types {
    NSString *tempString = @"";
    if (types == 0) { ///Documents
        ///输出: /var/mobile/Containers/Data/Application/8E016CC3-4574-40BB-80AB-8714FBF3C069/Documents
        tempString = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    } else if (types == 1) { ///tmp
        ///输出:private/var/mobile/Containers/Data/Application/8E016CC3-4574-40BB-80AB-8714FBF3C069/tmp/
        tempString = NSTemporaryDirectory();
    } else {
        tempString = @"非法参数";
    }
    return tempString;
}

遍历路径下指定后缀的所有文件(

///....................................................................................................
///遍历路径下指定后缀的所有文件(在fileArr变量获取结果)  path:目录路径  suffix:后缀名称 如:“.png” 要带点"."
- (void)getAllFileWithPath:(NSString *)path andSuffix:(NSString *)suffix {
    self.fileArrs = [NSMutableArray array];
    [self showAllFileWithPath:path andSuffix:suffix];
}
///此方法负责遍历
- (void)showAllFileWithPath:(NSString *)path andSuffix:(NSString *)suffix {
    NSFileManager * fileManger = [NSFileManager defaultManager];
    BOOL isDir = NO;
    BOOL isExist = [fileManger fileExistsAtPath:path isDirectory:&isDir];
    
    if (isExist) {
        if (isDir) {
            NSArray * dirArray = [fileManger contentsOfDirectoryAtPath:path error:nil];
            NSString * subPath = nil;
            for (NSString * str in dirArray) {
                subPath  = [path stringByAppendingPathComponent:str];
                BOOL issubDir = NO;
                [fileManger fileExistsAtPath:subPath isDirectory:&issubDir];
                [self showAllFileWithPath:subPath andSuffix:suffix];
            }
        } else {
            NSString *fileName = [[path componentsSeparatedByString:@"/"] lastObject];
            if ([fileName hasSuffix:suffix]) {
                ///打印文件名称如:  123.png
                [self.fileArrs addObject:fileName];
                ///NSLog(@" 文件名称======%@ ",fileName);
            }
        }
        
    } else {
        NSLog(@"this path is not exist!");
    }
}

判断设备是否是ipad

///判断设备是否是ipad  yes:ipad   no:非ipad
+ (BOOL)isIpads {
    NSString *deviceType = [UIDevice currentDevice].model;
    if ([deviceType isEqualToString:@"iPhone"]) {
        return NO;
    } else if ([deviceType isEqualToString:@"iPod touch"]) {
        return NO;
    } else if ([deviceType isEqualToString:@"iPad"]) {
        return YES;
    }
    return NO;
}

判断字符串内是否包含汉字

///判断字符串内是否包含汉字
+ (BOOL)isChinese:(NSString *)str {
    if (str.length == 0) {
        return NO;
    }
    
    for(int i = 0; i < [str length];i++) {
        int a = [str characterAtIndex:i];
        if( a > 0x4E00 && a < 0x9FFF) {
            NSLog(@"含有汉字");
            return YES;
        }
    }
    // NSLog(@"没有含有汉字");
    return NO;
}

判断字符串是否为纯数字 返回YES表示为纯数字,否则返回NO

///判断字符串是否为纯数字 返回YES表示为纯数字,否则返回NO
+ (BOOL) deptNumInputShouldNumber:(NSString *)str {
   if (str.length == 0) {
        return NO;
    }
    NSString *regex = @"[0-9]*";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    if ([pred evaluateWithObject:str]) {
        return YES;
    }
    return NO;
}

跳到指定vc

///跳到指定vc
+ (void)pushTargetVC:(id)objecs andVC:(UIViewController *)ctl {
    for (UIViewController *temp in ctl.navigationController.viewControllers){
        if ([temp isKindOfClass:objecs]) {
            [ctl.navigationController popToViewController:temp animated:YES];
        }
    }
}

校验图片是否为有效的PNG图片

/**
 *  校验图片是否为有效的PNG图片
 *  @param imageData 图片文件直接得到的NSData对象
 *  @return 是否为有效的PNG图片
 */
+ (BOOL)isValidPNGByImageData:(NSData *)imageData {
    UIImage* image = [UIImage imageWithData:imageData];
    /// 第一种情况:通过[UIImage imageWithData:data];直接生成图片时,如果image为nil,那么imageData一定是无效的
    if (imageData != nil && image == nil) {
        return NO;
    }
    
    /// 第二种情况:图片有部分是OK的,但是有部分坏掉了,它将通过第一步校验,那么就要用下面这个方法了。
    /// 将图片转换成PNG的数据,如果PNG数据能正确生成,那么这个图片就是完整OK的,如果不能,那么说明图片有损坏
    NSData* tempData = UIImagePNGRepresentation(image);
    if (tempData == nil) {
        return NO;
    } else {
        return YES;
    }
}

两个NSDate之间相隔

///两个NSDate之间相隔
+ (NSInteger)intervalSecondsWithSmallDate:(NSDate *)smallDate bigDate:(NSDate *)bigDate {
    NSCalendar *calendar =[NSCalendar currentCalendar];
    unsigned int unitFlags = kCFCalendarUnitYear|kCFCalendarUnitMonth|kCFCalendarUnitDay|kCFCalendarUnitHour|kCFCalendarUnitMinute|kCFCalendarUnitSecond;
    NSDateComponents *dateComp= [calendar components:unitFlags fromDate:smallDate toDate:bigDate options:0];
    NSInteger second = [dateComp hour]*3600+[dateComp minute]*60+[dateComp second];
    return second;
}

iOS二分查找算法

/**
 * 在某个数组中搜索目标(二分查找算法)
 * 优势:查询数据快  数组中10万条记录不到100毫秒就能查到
 *
 * 用法
 * NSArray * array1 = @[@3,@7,@9,@14,@25,@26,@37,@69];
 *  二分查找必须要先进行排序升序或者降序,注意对 array1进行排序,
 *
 * NSInteger result = [self binarySearchTarget:26 inArray:array1];
 *  NSLog(@" 888====》:%ld",(long)result); //打印找到的下标
 */
+ (NSInteger)binarySearchTarget:(NSInteger)target inArray:(NSArray *)arr {
    if (arr.count < 1) {
        //数组无元素,返回-1;
        return -1;
    }

    // 定义三个变量 第一个值下标、中间值下标、最后一个值下标
    NSInteger start = 0;
    NSInteger end = arr.count - 1;
    NSInteger mind = 0;

    // 进行循环 // 数组中第一个对象和最后一个对象之前还有其他对象则进行循环
    while (start < end - 1) {

        //会有一些朋友看到有些人是( start + end ) / 2这样写的,但是这样写有一点不好,就是start+end会出现整数溢出的情况,如果存在溢出,你再除以2也是没有用的,所以不能这么写
        mind = start + (end - start) / 2;

        // 如果中间值大于目标值
        if ([arr[mind] integerValue]> target) {
            end = mind; // 中间值做为最后一个值,在前半段再进行相同的搜索
        }else{
            start = mind;
        }
    }

    // 如果第一个值和目标值相等则获取第一个值的下标
    if ([arr[start] integerValue] == target) {
        return start;
    }

    // 如果最后一个值和目标值想等则获取最后一个下标
    if ([arr[end] integerValue] == target) {
        return end;
    }
    return -1;
}

一个大数组分割为N个数组

/**
 * 将数组分割为N份
 * 如数组: {1,2,3,4,5,6,7,8,9,10}  sizes:分组数量,比如array有10条数据 sizes为5 返回2组数据 每一组中又5条数据
 * 则返回:{{1,2,3,4,5},{6,7,8,9,10}}
 */
+(NSArray *)splitArray:(NSArray *)array withSize:(int)sizes {
    unsigned long count = array.count % sizes == 0 ? (array.count / sizes) : (array.count / sizes + 1);
    NSMutableArray *arr = [NSMutableArray array];
    for (int i = 0; i < count; i++) {
        int index = i * sizes;
        NSMutableArray * arr1 = [NSMutableArray array];
        [arr1 removeAllObjects];
        int j = index;
        while (j < sizes*(i + 1) && j < array.count) {
            [arr1 addObject:[array objectAtIndex:j]];
            j += 1;
        }
        [arr addObject:[arr1 copy]];
    }
    return [arr copy];
}

清除非UTF8内容(有时候data内有非UTF8内容导致dat转str后显示为null,此时可透过此方法清除)

///清除非UTF8内容(有时候data内有非UTF8内容导致dat转str后显示为null,此时可透过此方法清除)
+ (NSData *)cleanUTF8:(NSData *)data {
    /**
     用libiconv清除非utf8字符
     注意:
     依赖  #include "iconv.h"
     先给项目Link Binaries With Library 添加libiconv.dylib
     */
    iconv_t cd = iconv_open("UTF-8", "UTF-8"); // 从utf8转utf8
    int one = 1;
    iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one); // 丢弃不正确的字符
    
    size_t inbytesleft, outbytesleft;
    inbytesleft = outbytesleft = data.length;
    char *inbuf  = (char *)data.bytes;
    char *outbuf = malloc(sizeof(char) * data.length);
    char *outptr = outbuf;
    if (iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft)
        == (size_t)-1) {
        NSLog(@"this should not happen, seriously");
        return nil;
    }
    NSData *result = [NSData dataWithBytes:outbuf length:data.length - outbytesleft];
    iconv_close(cd);
    free(outbuf);
    return result;
}

系统原生分享

///原生分享文本  shareText:分享的文本  vc:当前控制器   rec:传入显示位置主要为了兼容ipad
+ (void)shareText:(NSString *)shareText vc:(UIViewController *)vc ipadFrame:(CGRect)rec {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSMutableArray *shareItems = [NSMutableArray array];
        if (shareText) {
            [shareItems addObject:shareText];
        }
        
        UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:shareItems applicationActivities:nil];
        
        ///兼容ipad
        if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad){
            activityVC.popoverPresentationController.sourceView = vc.view;
            activityVC.popoverPresentationController.sourceRect = rec;
        }
        
        //去除一些不需要的图标选项
        activityVC.excludedActivityTypes = @[UIActivityTypeAirDrop, UIActivityTypePostToWeibo, UIActivityTypePostToTencentWeibo];
        //成功失败的回调block
        UIActivityViewControllerCompletionWithItemsHandler myBlock = ^(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError) {
            
            if (completed){
                NSLog(@"分享完成completed");
            }else{
                NSLog(@"分享关闭canceled");
            }
        };
        activityVC.completionWithItemsHandler = myBlock;
        [vc presentViewController:activityVC animated:YES completion:nil];
    });
}

上一篇下一篇

猜你喜欢

热点阅读