iOS常用技术

0.科学上网

npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global

1.判断系统

#define UMSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

 调用方法:

UMSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0") //高于或等于 iOS8.0的系统

 

2.关于导航控制器下的高度 (以后整理)

iOS 7 :  viewDidLoad中   viewDidAppear:中

iOS 8及以后:viewDidLoad中   viewDidAppear:中

3.用逗号分隔一串数字

 1 - (void)formatMoney{
 2 
 3     NSInteger moneyNum = 11111111232332;
 4 
 5     NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
 6 
 7     formatter.numberStyle = NSNumberFormatterDecimalStyle;
 8 
 9     NSString* formatMoney = [formatter stringFromNumber:[NSNumber numberWithInteger:moneyNum]];
10 
11     NSLog(@"%@",formatMoney);
12 
13 }
View Code

4.nsdictionary的排序

 1         // 按等级从小到大排序
 2 
 3         NSArray *allKeys = [_dictLevelName allKeys];
 4 
 5         allKeys = [allKeys sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
 6 
 7             NSString *str1 = (NSString *)obj1;
 8 
 9             NSString *str2 = (NSString *)obj2;
10 
11             NSInteger level1 = [str1 integerValue];
12 
13             NSInteger level2 = [str2 integerValue];
14 
15             return [@(level1) compare:@(level2)];  // compare:是NSNumber 的函数,不可以比较字符串,需要单独转换.
16 
17         }];
18 
19         for (NSString *key in allKeys) {
20 
21             NSString *name = [_dictLevelName objectForKey:key];
22 
23             if (ISSTRING(name)) {
24 
25                 [_arrayLevelName addObject:name];
26 
27             }
28 
29         }
View Code

5.NSAssert作用:若程序在此处崩溃,就能在不插入全局断点的情况下,崩在此处,代替全局断点的作用.

NSAssert(view, @"View must not be nil.");崩溃,倒退崩溃到了我的代码

        [[PTVConfig instance] showToast:self.superview msg:@"解除屏蔽"];

是在 cell 中调用的,找不到父类 tableview 了,可见尽量少用 superview, 用父类作为代理直接处理.

6.查找最外层的控制器的方法:

    UITabBarController *tabBar = (UITabBarController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];

    UINavigationController *navi = tabBar.selectedViewController;

    UIViewController *vc = navi.visibleViewController;

7.关于手势

上面的手势对应的操作是: 
  • Tap(点一下)
  • Pinch(二指往內或往外拨动,平时经常用到的缩放)
  • Rotation(旋转)
  • Swipe(滑动,快速移动)
  • Pan (拖移,慢速移动)
  •  LongPress(长按)

8.运行 gif 图片,可以使用 UIImageView 动画. 代码如下:

 1 - (void)test {
 2     self.imgView.animationImages = [self animationImages]; //获取Gif图片列表
 3     self.imgView.animationDuration = 1;     //执行一次完整动画所需的时长
 4     self.imgView.animationRepeatCount = 0;  //动画重复次数
 5     [self.imgView startAnimating];
 6 }
 7 
 8 
 9 - (NSArray *)animationImages
10 {
11     NSFileManager *fielM = [NSFileManager defaultManager];
12     NSString *path = [[NSBundle mainBundle] pathForResource:@"vip_new_comer_tail" ofType:@"bundle"];
13     NSArray *arrays = [fielM contentsOfDirectoryAtPath:path error:nil];
14     
15     NSMutableArray *imagesArr = [NSMutableArray array];
16     for (NSString *name in arrays) {
17         NSString *imagePath = [path stringByAppendingPathComponent:name];
18         NSData *data = [NSData dataWithContentsOfFile:imagePath];
19         UIImage *image = [UIImage imageWithData:data];
20         if (image) {
21             [imagesArr addObject:image];
22         }
23     }
24     return imagesArr;
25 }
View Code

9.对于字符串形式保存的用户配置,若将其转换成字典,可以先使用方法将其转换成 NSData 对象,再将该对象装换成 NSDictionary 对象.

1     NSString *conf = [dict objectForKey:@"conf"];
2     if (conf) {
3         NSData * data = [conf dataUsingEncoding:NSUTF8StringEncoding];
4         if (data) {
5            NSDictionary *confDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
6         }
7     }
View Code

10.若给父视图添加了手势,则子视图UIControl 的点击事件被触发后,会先执行父视图的手势,后执行按钮的事件.

若想阻碍父视图的按钮事件,安静地执行按钮事件,可以在手势的delegate的代理方法中,查看当前用户点击的视图,来确定是否调用父视图的代理方法.

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     [self setupUI];
 4 }
 5 
 6 - (void)setupUI{
 7     UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onViewTouchDonw:)];
 8     recognizer.delegate = self;
 9     [self.view addGestureRecognizer:recognizer];
10     
11     [self.btn addTarget:self action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
12 }
13 
14 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
15 {
16     if([touch.view isKindOfClass:[UIButton class]])
17     {
18         NSLog(@"啦啦啦---%@",[touch.view class]);
19 
20         return NO;
21     }
22     return YES;
23 }
View Code

 11.判断麦克风和相机使用权限并打开的代码,iOS系统要在 plist 中添加信任的字符串,参考iOS 10 开发适配系列之权限Crash问题- 简书.

 1 /// 检查相机和麦克风的访问权限并提示设置
 2 - (BOOL)checkMediaTypeVideoAndAudio{
 3     BOOL bVideoAuthor = [self checkMediaTypeVideo];
 4     BOOL bAudioAuthor = [self checkMediaTypeAudio];
 5 
 6     if (bVideoAuthor && bAudioAuthor) {
 7         return YES;
 8     } else {
 9         return NO;
10     }
11 }
12 
13 /// 检查相机的访问权限并提示设置
14 - (BOOL)checkMediaTypeVideo{
15     __block BOOL bAuthor = NO;
16     AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
17     if (authStatus == AVAuthorizationStatusNotDetermined ||
18         authStatus == AVAuthorizationStatusDenied ){
19         
20         // 首次访问照像机权限的时候会弹出允许或不允许的对话框,后来访问失败的话,会在以下 block 中传值为 NO 的参数
21         [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
22             if (!granted) {
23                 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"请在\"设置-隐私-相机\"选项中,允许熊猫直播访问你的相机" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
24                 [alertView show];
25             } else {
26                 bAuthor = YES;
27             }
28         }];
29     }
30     return bAuthor;
31 }
32 
33 /// 检查麦克风的访问权限并提示设置
34 - (BOOL)checkMediaTypeAudio{
35     __block BOOL bAuthor = NO;
36     AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
37     if (authStatus == AVAuthorizationStatusNotDetermined ||
38         authStatus == AVAuthorizationStatusDenied ) {
39         
40         // 首次访问麦克风权限的时候会弹出允许或不允许的对话框,后来访问失败的话,会在以下 block 中传值为 NO 的参数
41         [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
42             if (!granted) {
43                 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"请在\"设置-隐私-麦克风\"选项中,允许熊猫直播访问你的麦克风" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
44                 [alertView show];
45             }
46         }];
47         
48     }
49     return bAuthor;
50 }
View Code

12.YYModel不同变量的使用方法

 1 + (NSDictionary *)modelCustomPropertyMapper {
 2     NSMutableDictionary *chatMappers = [@{@"text" : @"data.text",
 3                                   @"color" : @"data.color",
 4                                   @"size" : @"data.size",
 5                                   @"font" : @"data.font",
 6                                   } mutableCopy];
 7     NSDictionary *baseMappers = @{@"rid"  : @"from.rid",
 8                                   @"nick"  : @"from.nick",
 9                                   @"level"  : @"from.level",
10                                   @"fromLevelMin"  : @"from.level_min",
11                                   @"fromLevelMax"  : @"from.level_max",
12                                   @"exp"  : @"from.exp",
13                                   @"roleName"  : @"from.role_name",
14                                   @"roleVal" : @"from.role_val",
15                                   @"xroomId"  : @"to",
16                                   @"type"  : @"type",
17                                   };
18     [chatMappers addEntriesFromDictionary:baseMappers];
19     return chatMappers;
20 }
View Code

13.YYText 在 cell 中时,获取点击的位置

1 - (void)onTapChatMsg:(UITapGestureRecognizer *)tap{
2     CGRect rect = self.chatMsgLabel.textLayout.textBoundingRect;
3     CGPoint point = [tap locationInView:tap.view];
4     if (CGRectContainsPoint(rect, point)) {
5         NSLog(@"被点击了");
6     }
7 }
View Code

14.选中某个 cell 的常用代码:

 1 /// 某个 cell 是否被选中, 在 cellForItemAtIndexPath 代理方法中调用
 2 - (void)selectedCellIfNeeded:(PXYStickerCollectionViewCell *)cell indexPath:(NSIndexPath *)indexPath
 3 {
 4     if (self.lastSelectIndexPath == nil)
 5     {
 6         return;
 7     }
 8     if(indexPath.item == self.lastSelectIndexPath.item)
 9     {
10         cell.backgroundColor = [UIColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:0.4];
11         cell.gradientLayer.hidden = YES;
12     }
13     else
14     {
15         cell.backgroundColor = [UIColor clearColor];
16         cell.gradientLayer.hidden = NO;
17     }
18 }
19 
20 /// 选中某个 cell, 在 didSelectItemAtIndexPath 代理方法中调用
21 - (void)selectingIndexPath:(NSIndexPath *)indexPath collectionView:(UICollectionView *)collectionView{
22     
23     PXYStickerCollectionViewCell *cell = (PXYStickerCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
24     cell.backgroundColor = [UIColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:0.4];
25     cell.gradientLayer.hidden = YES;
26     
27     if (self.lastSelectIndexPath == nil)
28     {
29         self.lastSelectIndexPath = indexPath;
30         return;
31     }
32     else if (self.lastSelectIndexPath.item == indexPath.item)
33     {
34         return;
35     }
36     
37     PXYStickerCollectionViewCell *lastCell = (PXYStickerCollectionViewCell *)[collectionView cellForItemAtIndexPath:self.lastSelectIndexPath];
38     lastCell.backgroundColor = [UIColor clearColor];
39     lastCell.gradientLayer.hidden = NO;
40     self.lastSelectIndexPath = indexPath;
41 }
View Code

15.限制输入多少个字符

 1 - (void)textViewDidChange:(UITextView *)textView{
 2     NSString *lang = [[UIApplication sharedApplication]textInputMode].primaryLanguage; // 键盘输入模式
 3     if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写
 4         UITextRange *selectedRange = [textView markedTextRange];
 5         //获取高亮部分
 6         UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
 7         // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
 8         if (!position) {
 9             [self checkTextViewText:textView];
10         }
11         // 有高亮选择的字符串,则暂不对文字进行统计和限制
12         else{
13             [self checkTextViewText:textView];
14         }
15     }
16     // 中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
17     else{
18 
19     }
20 }
21 
22 - (void)textViewDidEndEditing:(UITextView *)textView{
23     [self checkTextViewText:textView];
24 }
25 
26 - (void)checkTextViewText:(UITextView *)textView {
27     if (textView.text.length > kMaxInputWindPlaneEditView) {
28         textView.text = [textView.text substringToIndex:kMaxInputWindPlaneEditView];
29         [[PTVConfig instance] showToast:self msg:[NSString stringWithFormat:@"文字长度不能超过%li个字符",(long)kMaxInputWindPlaneEditView]];
30     }
31 }
View Code

16.把崩溃日志转化为具体的某一行(crash 崩溃)(参考http://www.jianshu.com/p/da186c14db0f)

(/Users/liuzhu/Library/Developer/Xcode/DerivedData/xxx-atouolfjhjicfrgglhmhmicssual/Build/Products 中含有 dsym 文件)

1 chmod +x symbolicatecrash
2  export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"
3 ./symbolicatecrash 1460.crash PandaTV-ios.app.dSYM > Control_symbol.crash
View Code

(PS:Xcode7.3 symbolicatecrash路径
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

17.在分类中添加属性,核心代码如下:

 1 #import <objc/runtime.h>
 2 @property (nonatomic,assign) CGFloat count;
 3 
 4 -(void)setCount:(CGFloat)count{
 5     objc_setAssociatedObject(self, @selector(count), @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
 6 }
 7 
 8 -(CGFloat)count{
 9     NSNumber *count = objc_getAssociatedObject(self, @selector(count));
10     return count.floatValue;
11 }
View Code

 18.若 UIScrollView 的尺寸随着其中的图片尺寸在变化,则可以设置UIViewController中的automaticallyAdjustsScrollViewInsets属性来让其不变

1 - (void)viewDidLoad {
2     [super viewDidLoad];    
3     [self setAutomaticallyAdjustsScrollViewInsets:NO];
4 }
View Code

 

 

 

 

 

 

 

posted on 2016-08-22 11:21  活最好的自己  阅读(355)  评论(0编辑  收藏  举报

导航