iOS开发小技巧汇总
2018-07-28 本文已影响66人
八戒莫慌
美不美,看大腿(侵删)
解决办法:Go to your target Build Settings -> Other linker flags -> double click . Add $(inherited) to a new line.然后进入终端,执行pod update
网上还流行另外一种简单粗暴的方法:点击项目文件 project.xcodeproj,右键
1、设置导航条的颜色及title颜色
在navgationController里设置
//设置NavigationBar背景颜色
[[UINavigationBar appearance] setBarTintColor:[UIColor blueColor]];
//@{}代表Dictionary
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
在viewController里设置
//set NavigationBar 背景颜色&title 颜色
[self.navigationController.navigationBar setBarTintColor:IFBackgroundColor];
[self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor],UITextAttributeTextColor,nil]];
2.设置UIButton在选中状态的背景颜色
3.从字符串中取出数字
/** ---------------------------------------------------------------------------*/
第一种:
字符串: urlString
NSScanner *scanner = [NSScanner scannerWithString:urlString];
[scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:nil];
int number;
[scanner scanInt:&number];
NSString *num=[NSString stringWithFormat:@"%d",number];
/** ---------------------------------------------------------------------------*/
第二种:
字符串: urlString
NSCharacterSet* nonDigits =[[NSCharacterSet decimalDigitCharacterSet] invertedSet];
int remainSecond =[[urlString stringByTrimmingCharactersInSet:nonDigits] intValue];
NSLog(@" num %d ",remainSecond);
4.颜色转换为背景图片
//颜色转换为背景图片
-(UIImage *)imageWithColor:(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 *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
5.CoreText实现图文混排之文字环绕及点击算法
http://blog.csdn.net/qq_30513483/article/details/53883865
6.UILabel显示HTML文本
NSString * htmlString = @"<html><body> Some html string \n <font size=\"13\"color=\"red\">This is some text!</font> </body></html>";
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
UILabel * myLabel = [[UILabel alloc] initWithFrame:self.view.bounds];
myLabel.attributedText = attrStr;
[self.view addSubview:myLabel];
7.正则匹配html 代码中的图片
- (NSArray *)filterImage:(NSString *)html
{
NSMutableArray *resultArray = [NSMutableArray array];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"<(img|IMG)(.*?)(/>|></img>|>)" options:NSRegularExpressionAllowCommentsAndWhitespace error:nil];
NSArray *result = [regex matchesInString:html options:NSMatchingReportCompletion range:NSMakeRange(0, html.length)];
for (NSTextCheckingResult *item in result) {
NSString *imgHtml = [html substringWithRange:[item rangeAtIndex:0]];
NSArray *tmpArray = nil;
if ([imgHtml rangeOfString:@"src=\""].location != NSNotFound) {
tmpArray = [imgHtml componentsSeparatedByString:@"src=\""];
} else if ([imgHtml rangeOfString:@"src="].location != NSNotFound) {
tmpArray = [imgHtml componentsSeparatedByString:@"src="];
}
if (tmpArray.count >= 2) {
NSString *src = tmpArray[1];
NSUInteger loc = [src rangeOfString:@"\""].location;
if (loc != NSNotFound) {
src = [src substringToIndex:loc];
[resultArray addObject:src];
}
}
}
return resultArray;
}
8.不运行xcode 查看打印日志的方法
方法一:手机连上电脑,打开Xcode,选择菜单中的‘Window’ -> 'Devices',这里可以看到所以打印的日志(不只是你的app)
方法二:可以添加代码,写到沙盒中的文件去,在plist中设置可以共享,然后运行,就可以用iTune找到相应文件。不过这个代码量比较大,而且只能用于调试。
9.AFNetWorking Post请求,请求参数放在Body处
10.时间段判断
方法一:
/**
* 判断当前时间是否处于某个时间段内
*
* @param startTime 开始时间
* @param expireTime 结束时间
*/
- (BOOL)validateWithStartTime:(NSString *)startTime withExpireTime:(NSString *)expireTime {
NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
// 时间格式,此处遇到过坑,建议时间HH大写,手机24小时进制和12小时进制都可以完美格式化
[dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
NSDate *start = [dateFormat dateFromString:startTime];
NSDate *expire = [dateFormat dateFromString:expireTime];
NSLog(@"---===%@",dateFormat);
if ([today compare:start] == NSOrderedDescending && [today compare:expire] == NSOrderedAscending) {
return YES;
}
return NO;
}
方法二:
/**
if ([self isBetweenFromHour:9 toHour:15]) {
LOG(@"处于时间段内");
}else {
LOG(@"处于时间段外");
}
* @brief 判断当前时间是否在fromHour和toHour之间。如, fromHour=8,toHour=23时,即为判断当前时间是否在8:00-23:00之间
*/
- (BOOL)isBetweenFromHour:(NSInteger)fromHour andMinute:(NSInteger)fromMinute toHour:(NSInteger)toHour andToMinute:(NSInteger)toMinute {
NSDate *dateFrom = [self getCustomDateWithHour:fromHour minute:fromMinute];
NSDate *dateTo = [self getCustomDateWithHour:toHour minute:toMinute];
NSDate *currentDate = [NSDate date];
// NSLog(@"dateFrom=%@---dateTo=%@---currentDate=%@",dateFrom,dateTo,currentDate);
if ([currentDate compare:dateFrom]==NSOrderedDescending && [currentDate compare:dateTo]==NSOrderedAscending) {
// 当前时间在9点和10点之间
return YES;
}
return NO;
}
/**
* @brief 生成当天的某个点(返回的是伦敦时间,可直接与当前时间[NSDate date]比较)
* @param hour 如hour为“8”,就是上午8:00(本地时间)
*/
- (NSDate *)getCustomDateWithHour:(NSInteger)hour minute:(NSInteger)minute {
//获取当前时间
NSDate *currentDate = [NSDate date];
NSCalendar *currentCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *currentComps = [[NSDateComponents alloc] init];
NSInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
currentComps = [currentCalendar components:unitFlags fromDate:currentDate];
//设置当天的某个点
NSDateComponents *resultComps = [[NSDateComponents alloc] init];
[resultComps setYear:[currentComps year]];
[resultComps setMonth:[currentComps month]];
[resultComps setDay:[currentComps day]];
[resultComps setHour:hour];
[resultComps setMinute:minute];
NSCalendar *resultCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
return [resultCalendar dateFromComponents:resultComps];
}
11 cocoapods报错
- Use the `$(inherited)` flag, or
- Remove the build settings from the target.
8557AAAD-6A45-4DED-AE03-50D7663F9C42.png
解决办法:Go to your target Build Settings -> Other linker flags -> double click . Add $(inherited) to a new line.然后进入终端,执行pod update
网上还流行另外一种简单粗暴的方法:点击项目文件 project.xcodeproj,右键
显示包内容
,用文本编辑器打开project.pbxproj
,删除OTHER_LDFLAGS
的地方,保存,回到 Xcode,编译通过。
12 UITextfield小数点后只显示两位有效数字
方法一:
@property (nonatomic, assign) BOOL isHaveDian;
@property (nonatomic, assign) BOOL isFirstZero;
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == self.textField) {
if ([textField.text rangeOfString:@"."].location==NSNotFound) {
_isHaveDian = NO;
}
if ([textField.text rangeOfString:@"0"].location==NSNotFound) {
_isFirstZero = NO;
}
if ([string length]>0)
{
unichar single=[string characterAtIndex:0];//当前输入的字符
if ((single >='0' && single<='9') || single=='.')//数据格式正确
{
if([textField.text length]==0){
if(single == '.'){
//首字母不能为小数点
return NO;
}
if (single == '0') {
_isFirstZero = YES;
return YES;
}
}
if (single=='.'){
if(!_isHaveDian)//text中还没有小数点
{
_isHaveDian=YES;
return YES;
}else{
return NO;
}
}else if(single=='0'){
if ((_isFirstZero&&_isHaveDian)||(!_isFirstZero&&_isHaveDian)) {
//首位有0有.(0.01)或首位没0有.(10200.00)可输入两位数的0
if([textField.text isEqualToString:@"0.0"]){
return NO;
}
NSRange ran=[textField.text rangeOfString:@"."];
int tt=(int)(range.location-ran.location);
if (tt <= 2){
return YES;
}else{
return NO;
}
}else if (_isFirstZero&&!_isHaveDian){
//首位有0没.不能再输入0
return NO;
}else{
return YES;
}
}else{
if (_isHaveDian){
//存在小数点,保留两位小数
NSRange ran=[textField.text rangeOfString:@"."];
int tt= (int)(range.location-ran.location);
if (tt <= 2){
return YES;
}else{
return NO;
}
}else if(_isFirstZero&&!_isHaveDian){
//首位有0没点
return NO;
}else{
return YES;
}
}
}else{
//输入的数据格式不正确
return NO;
}
}else{
return YES;
}
}
return YES;
}
方法二:
// 小数点后只显示两位有效数字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
//删除处理
if ([string isEqualToString:@""]) {
return YES;
}
//首位不能为.号
if (range.location == 0 && [string isEqualToString:@"."]) {
return NO;
}
return [self isRightInPutOfString:textField.text withInputString:string range:range];
}
- (BOOL)isRightInPutOfString:(NSString *) string withInputString:(NSString *) inputString range:(NSRange) range{
//判断只输出数字和.号
NSString *passWordRegex = @"[0-9\\.]";
NSPredicate *passWordPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",passWordRegex];
if (![passWordPredicate evaluateWithObject:inputString]) {
return NO;
}
//逻辑处理
if ([string containsString:@"."]) {
if ([inputString isEqualToString:@"."]) {
return NO;
}
NSRange subRange = [string rangeOfString:@"."];
if (range.location - subRange.location > 2) {
return NO;
}
}
return YES;
}
13 AutoLayout下多行UILabel无法显示多行文本的问题
设置UILabel的preferredMaxLayoutWidth属性
14 数组的排序(升序、降序及乱序)
#pragma mark -- 数组排序方法(升序)
- (void)arraySortASC {
//定义一个数字数组
// NSArray *array = @[@"B",@"E",@"A",@"D",@"C"];
//对数组进行排序
NSArray *result = [array sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSLog(@"%@~%@",obj1,obj2); //3~4 2~1 3~1 3~2
return [obj1 compare:obj2]; //升序
}];
NSLog(@"result=%@",result);
}
#pragma mark -- 数组排序方法(降序)
- (void)arraySortDESC{
//定义一个数字数组
NSArray *array = @[@(3),@(4),@(2),@(1)];
//对数组进行排序
NSArray *result = [array sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSLog(@"%@~%@",obj1,obj2); //3~4 2~1 3~1 3~2
return [obj2 compare:obj1]; //降序
}];
NSLog(@"result=%@",result);
}
#pragma mark -- 数组排序方法(乱序)
- (void)arraySortBreak{
//定义一个数字数组
NSArray *array = @[@(3),@(4),@(2),@(1),@(5),@(6),@(0)];
//对数组进行排序
NSArray *result = [array sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSLog(@"%@~%@",obj1,obj2);
//乱序
if (arc4random_uniform(2) == 0) {
return [obj2 compare:obj1]; //降序
}
else{
return [obj1 compare:obj2]; //升序
}
}];
NSLog(@"result=%@",result);
}
15 iOS APP上传iTunes Store 时,报错 An error occurred uploading to the iTunes Store!
1.Open the terminal and run these commands:
cd ~
mv .itmstransporter/ .old_itmstransporter/
2.把发布证书删除了,重新创建
3.解决打包上传一直停留在authenticating with the itunes store问题
1. cd ~
2. mv .itmstransporter/ .old_itmstransporter/
3. "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/bin/iTMSTransporter"
注意:一定要等第三条命令执行完毕才可以哦!
16.webview高度
// 网页开始加载完成
- (void)webViewDidFinishLoad:(UIWebView *)webView {
newsDetails_H = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
}
17.强制删除iTunes
image.png18,版本更新提示
https://www.jianshu.com/p/032b5eb67002
1)后台版本判断(推荐)
image.png2)ios端版本判断(不建议使用)
#pragma mark - checkV
-(void)VersonUpdate{
//定义的app的地址
NSString *urld = [NSString stringWithFormat:@"http://itunes.apple.com/lookup?id=%@",@"appID"];
//网络请求app的信息,主要是取得我说需要的Version
NSURL *url = [NSURL URLWithString:urld];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:10];
[request setHTTPMethod:@"POST"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSMutableDictionary *receiveStatusDic=[[NSMutableDictionary alloc]init];
if (data) {
//data是有关于App所有的信息
NSDictionary *receiveDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
if ([[receiveDic valueForKey:@"resultCount"] intValue]>0) {
[receiveStatusDic setValue:@"1" forKey:@"status"];
[receiveStatusDic setValue:[[[receiveDic valueForKey:@"results"] objectAtIndex:0] valueForKey:@"version"] forKey:@"version"];
//请求的有数据,进行版本比较
[self performSelectorOnMainThread:@selector(receiveData:) withObject:receiveStatusDic waitUntilDone:NO];
}else{
[receiveStatusDic setValue:@"-1" forKey:@"status"];
}
}else{
[receiveStatusDic setValue:@"-1" forKey:@"status"];
}
}];
[task resume];
}
-(void)receiveData:(id)sender
{
//获取APP自身版本号
NSString *localVersion = [[[NSBundle mainBundle]infoDictionary]objectForKey:@"CFBundleShortVersionString"];
NSArray *localArray = [localVersion componentsSeparatedByString:@"."];
NSArray *versionArray = [sender[@"version"] componentsSeparatedByString:@"."];
if ((versionArray.count == 3) && (localArray.count == versionArray.count)) {
if ([localArray[0] intValue] < [versionArray[0] intValue]) {
[self updateVersion];
}else if ([localArray[0] intValue] == [versionArray[0] intValue]){
if ([localArray[1] intValue] < [versionArray[1] intValue]) {
[self updateVersion];
}else if ([localArray[1] intValue] == [versionArray[1] intValue]){
if ([localArray[2] intValue] < [versionArray[2] intValue]) {
[self updateVersion];
}
}
}
}
}
-(void)updateVersion{
NSString *msg = [NSString stringWithFormat:@"升级到最新版本"];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"升级提示" message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *otherAction = [UIAlertAction actionWithTitle:@"现在升级"style:UIAlertActionStyleDestructive handler:^(UIAlertAction*action) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"你的app在商店的下载地址"]];
[[UIApplication sharedApplication]openURL:url];
}];
[alertController addAction:otherAction];
[self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
}
19.程序生命周期
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#pragma mark -- NSLog(@"\n ===> 程序开始 !");
self.window = [[UIWindow alloc]initWithFrame:CGRectMake(0, 0, SCREENW, SCREENH)];
self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[[ViewController alloc]init]];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
#pragma mark -->NSLog(@"\n ===> 程序挂起 !");
#pragma mark -->比如:当有电话进来或者锁屏,这时你的应用程会挂起,在这时,UIApplicationDelegate委托会收到通知,调用 applicationWillResignActive 方法,你可以重写这个方法,做挂起前的工作,比如关闭网络,保存数据。
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
#pragma mark --> NSLog(@"\n ===> 程序进入后台 !");
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
#pragma mark --> NSLog(@"\n ===> 程序进入前台 !");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
#pragma mark --> NSLog(@"\n ===> 程序重新激活 !");
#pragma mark -->应用程序在启动时,在调用了 applicationDidFinishLaunching 方法之后也会调用 applicationDidBecomeActive 方法,所以你要确保你的代码能够分清复原与启动,避免出现逻辑上的bug。(大白话就是说:只要启动app就会走此方法)。
}
- (void)applicationWillTerminate:(UIApplication *)application {
#pragma mark --> 当用户按下按钮,或者关机,程序都会被终止。当一个程序将要正常终止时会调用 applicationWillTerminate 方法。但是如果长主按钮强制退出,则不会调用该方法。这个方法该执行剩下的清理工作,比如所有的连接都能正常关闭,并在程序退出前执行任何其他的必要的工作.
}
20.解决ios11的下移问题
//解决ios11的下移问题
if ([_YDHomeTableView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
if (@available(iOS 11.0, *)) {
_YDHomeTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
}
}
21.获取图片大小
+ (CGSize)bmpImageSizeWithHeaderData:(NSData *)data {
if (data.length != 8) {
return CGSizeZero;
}
unsigned char w1 = 0, w2 = 0, w3 = 0, w4 = 0;
[data getBytes:&w1 range:NSMakeRange(0, 1)];
[data getBytes:&w2 range:NSMakeRange(1, 1)];
[data getBytes:&w3 range:NSMakeRange(2, 1)];
[data getBytes:&w4 range:NSMakeRange(3, 1)];
int w = w1 + (w2 << 8) + (w3 << 16) + (w4 << 24);
unsigned char h1 = 0, h2 = 0, h3 = 0, h4 = 0;
[data getBytes:&h1 range:NSMakeRange(4, 1)];
[data getBytes:&h2 range:NSMakeRange(5, 1)];
[data getBytes:&h3 range:NSMakeRange(6, 1)];
[data getBytes:&h4 range:NSMakeRange(7, 1)];
int h = h1 + (h2 << 8) + (h3 << 16) + (h4 << 24);
return CGSizeMake(w, h);
}
22. iOS获取本机的UDID
什么是UDID?
UDID,是iOS设备的一个唯一识别码,每台iOS设备都有一个独一无二的编码,这个编码,我们称之为识别码,也叫做UDID( Unique Device Identifier)。
1.使用蒲公英一步快速获取 iOS 设备的 UDID
使用 iPhone 或 iPad 上的 Safari 浏览器打开链接:https://www.pgyer.com/udid,即可快速获取 UDID(如果系统提示输入密码,请输入锁屏密码。)
2.iOS获取本机的UDID命令行
在终端输入命令行
instruments-s|awk'{print $NR}'|sed-n3p|awk'{print substr($0,2,length($0)-2)}'|xargsrvictl-s
然后只要连上手机,就可以直接获取到 UDID 了
UDID :是用来标示设备的唯一性。
UUID :是用来标示同一个设备上不同应用之间的唯一性。
23. iOS获取手机壳颜色
- (void)getPhoneColor {
NSString *deviceColor;
NSString *deviceEnclosureColor;//手机壳颜色
UIDevice *device = [UIDevice currentDevice];
SEL selector = NSSelectorFromString(@"deviceInfoForKey:");
if (![device respondsToSelector:selector]) {
selector = NSSelectorFromString(@"_deviceInfoForKey:");
}
if ([device respondsToSelector:selector]) {
IMP imp = [device methodForSelector:selector];
NSString *(*func)(id, SEL, NSString *) = (void *)imp;
deviceColor = func(device, selector, @"DeviceColor");
deviceEnclosureColor = func(device, selector, @"DeviceEnclosureColor");
NSLog(@"color=%@,手机壳颜色=%@",deviceColor,deviceEnclosureColor);
}
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 150, 60, 100)];
[self.view addSubview:view1];
view1.backgroundColor=[self colorWithHexString:deviceEnclosureColor];
}
- (UIColor *) colorWithHexString: (NSString *)color {
NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
// String should be 6 or 8 characters
if ([cString length] < 6) {
return [UIColor clearColor];
}
// 判断前缀
if ([cString hasPrefix:@"0X"])
cString = [cString substringFromIndex:2];
if ([cString hasPrefix:@"#"])
cString = [cString substringFromIndex:1];
if ([cString length] != 6)
return [UIColor clearColor];
// 从六位数值中找到RGB对应的位数并转换
NSRange range;
range.location = 0;
range.length = 2;
//R、G、B
NSString *rString = [cString substringWithRange:range];
range.location = 2;
NSString *gString = [cString substringWithRange:range];
range.location = 4;
NSString *bString = [cString substringWithRange:range];
// Scan values
unsigned int r, g, b;
[[NSScanner scannerWithString:rString] scanHexInt:&r];
[[NSScanner scannerWithString:gString] scanHexInt:&g];
[[NSScanner scannerWithString:bString] scanHexInt:&b];
return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
}
24.WKWebView获取内容高度建议使用方法
[webView evaluateJavaScript:@"document.body.offsetHeight;" completionHandler:^(id _Nullable any, NSError * _Nullable error) {
//webView内容高度
NSString *heightStr = [NSString stringWithFormat:@"%@",any];
}];