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];
});
}