iOS部分小技巧 持续更新中
来源:互联网 发布:四级网络课程哪个好 编辑:程序博客网 时间:2024/05/16 15:35
- 可以在viewWillDisappear中判断下一个页面是pop、push还是present的
- 画圆的三种方式
- 获取当前控制器
- 消除警告
- UIButton中的TitleEdgeInsets使用
- 定位后的反编译和地区中文首字母缩写
- 更改 UINavigationBar 的返回键文字(同时保留右滑返回)
- NSDictionary/NSArray 转 JSON字符串
- KeyChain 保存密码
- 退出到最外层
- 关于 dispatch_barrier_async 的使用
1、可以在viewWillDisappear中判断下一个页面是pop、push还是present的
NSArray *viewControllers = self.navigationController.viewControllers; if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) { // View is disappearing because a new view controller was pushed onto the stack NSLog(@"New view controller was pushed"); } else if ([viewControllers indexOfObject:self] == NSNotFound) { // View is disappearing because it was popped from the stack NSLog(@"View controller was popped"); } else if (viewControllers.count <= 1) { NSLog(@"View controller was present"); }
2、画圆的三种方式
1. 贝塞尔曲线画范围,Context上下文截取
- (UIImage *)makeRoundImage:(UIImage *)image { CGFloat imageWidth = image.size.width; CGFloat imageHeight = image.size.height; UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageWidth, imageHeight), NO, 0.0); UIGraphicsGetCurrentContext(); CGFloat radius = (imageWidth < imageHeight?imageHeight:imageHeight)*0.5; UIBezierPath *Bezier = [UIBezierPath bezierPathWithArcCenter:CGPointMake(imageWidth*0.5, imageHeight*0.5) radius:radius startAngle:0 endAngle:M_PI*2 clockwise:YES]; [Bezier stroke]; [Bezier addClip]; [image drawInRect:CGRectMake(0, 0, imageWidth, imageHeight)]; UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; }
2. layer.cornerRadius设置为高度的一半,前提是宽高相同
UIImageView *imageView = [UIImageView new]; imageView.layer.masksToBounds = YES; imageView.layer.cornerRadius = CGRectGetWidth(imageView.bounds)/2.0;
3. 直接通过sb跟xib设置,不过需要设置成固定值 http://www.360doc.com/content/15/0128/17/20918780_444509231.shtml
3、获取当前控制器
+ (UIViewController *)getCurrentVC{ UIViewController *result = nil; UIWindow * window = [[UIApplication sharedApplication] keyWindow]; //app默认windowLevel是UIWindowLevelNormal,如果不是,找到UIWindowLevelNormal的 if (window.windowLevel != UIWindowLevelNormal) { NSArray *windows = [[UIApplication sharedApplication] windows]; for(UIWindow * tmpWin in windows) { if (tmpWin.windowLevel == UIWindowLevelNormal) { window = tmpWin; break; } } } id nextResponder = nil; UIViewController *appRootVC=window.rootViewController; // 如果是present上来的appRootVC.presentedViewController 不为nil if (appRootVC.presentedViewController) { nextResponder = appRootVC.presentedViewController; }else{ UIView *frontView = [[window subviews] objectAtIndex:0]; nextResponder = [frontView nextResponder]; } if ([nextResponder isKindOfClass:[UITabBarController class]]){ UITabBarController * tabbar = (UITabBarController *)nextResponder; UINavigationController * nav = (UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex]; // UINavigationController * nav = tabbar.selectedViewController ; 上下两种写法都行 result=nav.childViewControllers.lastObject; }else if ([nextResponder isKindOfClass:[UINavigationController class]]){ UIViewController * nav = (UIViewController *)nextResponder; result = nav.childViewControllers.lastObject; }else{ result = nextResponder; } return result;}
4、消除警告
http://www.jianshu.com/p/eb03e20f7b1c
5、UIButton中的TitleEdgeInsets使用
UIButton中的ImageEdgeInsets与TitleEdgeInsets都是针对当前位置生效的,即设置UIEdgeInsetsMake(a, b, c, d)则意味着向上偏移a、向左偏移b、向下偏移c、向右偏移d
6、定位后的反编译和地区中文首字母缩写
CLLocation *location = locations.lastObject; CLGeocoder *revGeo = [[CLGeocoder alloc] init]; [revGeo reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { NSDictionary *dict = [[placemarks objectAtIndex:0] addressDictionary]; NSString *state = dict[@"State"]; NSMutableString *str = [NSMutableString stringWithString:state]; CFStringTransform((CFMutableStringRef) str, NULL, kCFStringTransformMandarinLatin, NO); CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO); NSString *pinYin = [str capitalizedString]; NSArray *pinyinArr = [pinYin componentsSeparatedByString:@" "]; NSMutableString *totalString = [NSMutableString string]; for (int i=0; i<pinyinArr.count; i++) { if (i != pinyinArr.count-1 || (![pinyinArr[i] isEqualToString:@"Sheng"] && [pinyinArr[i] isEqualToString:@"Shi"])) { NSString *nowState = pinyinArr[i]; [totalString appendString:[nowState substringToIndex:1]]; } } NSLog(@"%@",totalString); }];
7、更改 UINavigationBar 的返回键文字(同时保留右滑返回)
目前为止,查到了许多种做法,然而实验之后发现,可行的暂且是有一种
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleDone target:self action:nil];
这里更改的是下一个 Push 过去的控制器的返回键的文字,图案的样式保留。
8、NSDictionary/NSArray 转 JSON字符串
+ (NSString *)jsonStringFormDict:(NSDictionary *)dict { NSMutableString *jsonString = [NSMutableString string]; [jsonString appendString:@"{"]; [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { if (jsonString.length > 1) { [jsonString appendString:@","]; } [jsonString appendFormat:@"\"%@\":",key]; if ([obj isKindOfClass:[NSArray class]]) { [jsonString appendString:[self jsonStringFormArray:obj]]; } else { if ([obj isKindOfClass:[NSDictionary class]]) { [jsonString appendString:[self jsonStringFormDict:obj]]; } else { [jsonString appendFormat:@"\"%@\"",obj]; } } }]; [jsonString appendString:@"}"]; return jsonString;}+ (NSString *)jsonStringFormArray:(NSArray *)array { NSMutableString *jsonString = [NSMutableString string]; [jsonString appendString:@"["]; for (int i=0; i<array.count; i++) { if (i != 0) { [jsonString appendString:@","]; } if ([array[i] isKindOfClass:[NSDictionary class]]) { [jsonString appendString:[self jsonStringFormDict:array[i]]]; } else { if ([array[i] isKindOfClass:[NSArray class]]) { [jsonString appendString:[self jsonStringFormArray:array[i]]]; } else { [jsonString appendFormat:@"\"%@\"",array[i]]; } } } [jsonString appendString:@"]"]; return jsonString;}
9、KeyChain 保存密码
- 打开 Capabilities 中的 Keychain Sharing 开关,否则在 iOS10 中会崩溃。
- 导入 Security.framework
- 编写 KeyChain 文件
//// XWSDKeyChain.h// XWSDCarLoan//// Created by chenjintian on 17/2/13.// Copyright © 2017年 CJT. All rights reserved.//#import <Foundation/Foundation.h>@interface XWSDKeyChain : NSObject+ (void)save:(NSString *)service data:(id)data;+ (id)load:(NSString *)service;+ (void)delete:(NSString *)service;@end//// XWSDKeyChain.m// XWSDCarLoan//// Created by chenjintian on 17/2/13.// Copyright © 2017年 CJT. All rights reserved.//#import "XWSDKeyChain.h"#import <Security/Security.h>@implementation XWSDKeyChain+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (id)kSecClassGenericPassword,(id)kSecClass, service, (id)kSecAttrService, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil];}+ (void)save:(NSString *)service data:(id)data { //Get search dictionary NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Delete old item before add new item SecItemDelete((CFDictionaryRef)keychainQuery); //Add new object to search dictionary(Attention:the data format) [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData]; //Add item to keychain with the search dictionary SecItemAdd((CFDictionaryRef)keychainQuery, NULL);}+ (id)load:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Configure the search setting //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; CFDataRef keyData = NULL; if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { @try { ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } if (keyData) CFRelease(keyData); return ret;}+ (void)delete:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((CFDictionaryRef)keychainQuery);}@end
10、退出到最外层
presentingViewController:
UIViewController *vc = self;while (vc.presentingViewController) { vc = vc.presentingViewController;}[vc dismissViewControllerAnimated:YES completion:nil];
pushViewController:
[self.navigationController popToRootViewControllerAnimated:YES];
11、关于 dispatch_barrier_async 的使用
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-1"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-2"); }); dispatch_barrier_async(concurrentQueue, ^(){ NSLog(@"dispatch-barrier"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-3"); }); dispatch_async(concurrentQueue, ^(){ NSLog(@"dispatch-4"); });
代码是拷贝的,理解是自己的。
barrier 的翻译是栅栏,在代码中的意思就是用来分割、确定线程,在上面的输出中,前面两个输出1、2顺序不定,第三个一定为dispatch-barrier,第四五个输出3、4顺序也不定。此为分割效果
也可以放在最后,作为一个前面的线程都处理完毕的标记。
0 0
- iOS部分小技巧 持续更新中
- iOS开发中总结的小技巧(持续更新中)
- iOS开发小技巧(持续更新中)
- IOS 小技巧积累(持续更新)
- IOS 小技巧 (持续更新ing.....)
- iOS 开发小技巧-持续更新~
- iOS小技巧总结(持续更新)
- iOS小技巧总结(持续更新)
- iOS小技巧纪录(持续更新)
- 小技巧 ASP.NET 持续更新中
- 编程小技巧(持续更新中)
- matlab点滴小技巧 (持续更新中)
- div+css小技巧(持续更新中)
- 小技巧(持续更新)
- iOS学习笔记之开发实用小技巧(持续更新)
- CSS 小技巧(持续更新)
- LINUX小技巧!持续更新......
- js小技巧(持续更新)
- 关于共享单车定位不准问题
- Java 性能分析工具
- Failed to load JavaHL Library.
- 又见01背包
- C语言学习中遇到的一些关键字
- iOS部分小技巧 持续更新中
- 【DRP分销资源计划】——oracle无法正常工作的解决办法
- Gradle中SDK版本及versoin版本的含义
- Redis整合Spring综合使用缓存实例
- ubuntu 定时脚本折腾札记
- Java字节码文件虚拟指令集简介
- STM8L051之通过ADC1与DMA读取内部参考电压,求取VDD电源电压---库函数版
- 美团Android自动化之旅—适配渠道包
- 一种解决运行程序报“应用程序配置不正确”的问题