【iOS】iOS6兼容性问题小结

上次说到了iphone5的一些兼容性解决的东西,这次谈一下平时开发时遇到的一些iOS6的兼容性问题。

 

1、首先是Oritentation问题:

这里可以看这篇翻译:http://blog.csdn.net/sandy_kisa/article/details/8037699

但事实上iOS6对于plist非常敏感,如果仅仅按照上面改可能还是会出现问题,我就碰到了,如果plist中UISupportedInterfaceOrientations项目的原有支持三个方向改为只有一个:Portrait (bottom home button),这样就没啥问题了

 

2、UIImageView上的UIButton点击触发问题:

在iOS6一下的版本我们如果在UIImageView addSubview一个UIButton,则对该button进行事件触发绑定是办不到的,而在iOS6中又是可以的,可能是apple发现了这个存在的bug。(有人会问干嘛要直接在image上add一个button啊,在view上直接叠加不就行了,但是如果要做图片的选择等操作,add在image上的复杂度会比直接再view上add要低很多)

我们做兼容可以这样:

 

C代码   收藏代码
  1. -(void)viewDidLoad  
  2. {  
  3.        singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];  
  4.        [self.view addGestureRecognizer:singleTap];  
  5. }  
  6.   
  7. -(void)handleSingleTap:(UITapGestureRecognizer*)gesture  
  8. {  
  9.     if (gesture.state == UIGestureRecognizerStateEnded) {  
  10.           
  11.         CGPoint tapPoint = [gesture locationInView:blackBackgroundView];  
  12.         if ((tapPoint.x > (ScreenWidth - 75) && tapPoint.y > (ScreenHeight - 75) && !isPhotoGif) || (tapPoint.x > (ScreenHeight - 75) && tapPoint.y > (ScreenWidth - 75) && !isPhotoGif)) {  
  13.             [self saveButtonPressed:nil];  
  14.             return;  
  15.         }  
  16. }  

 

 上面对于tap手势的point进行判断再触发,而在ios6中则是直接绑定事件触发器

【2013.5.14补充】后来发现其实原因是iOS6中直接给UIImageView的userInteractionEnabled开启为YES的缘故,事实上本来就能够通过userInteractionEnabled改为YES解决上述UIButton在UIImageView中无法响应的问题。

 

3、通讯录的隐私问题

iOS6中新增加了用户的隐私设置,所以在app需要访问用户的通讯录的时候需要用户允许。而以前广泛用的ABContact类库不包含这些东西。我们现在要对ABContact进行更改:

iOS中新增ABAddressBookCreateWithOptions方法我们要加入ABContact中,尼玛ABContact这货三年没更新了。。。

将原来getter方法:

 

C代码   收藏代码
  1. + (ABAddressBookRef) addressBook  
  2. {  
  3.     return CFAutorelease(ABAddressBookCreate());  
  4. }  

 

 改为:

 

C代码   收藏代码
  1. + (ABAddressBookRef) addressBook  
  2. {  
  3.     ABAddressBookRef addressBook = nil;  
  4.     if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0)  
  5.     {  
  6.         addressBook = ABAddressBookCreateWithOptions(NULL, NULL);  
  7.         //等待同意后向下执行  
  8.         dispatch_semaphore_t sema = dispatch_semaphore_create(0);  
  9.         ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)  
  10.                                                  {  
  11.                                                      dispatch_semaphore_signal(sema);  
  12.                                                  });  
  13.         dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);  
  14.         dispatch_release(sema);  
  15.     }  
  16.     else  
  17.     {  
  18.         addressBook = ABAddressBookCreate();  
  19.     }  
  20.     return CFAutorelease(addressBook);  
  21. }  

 

 上面的代码是一个需要用户同意的代码片段。

接着要对其余的CFAutorelease(ABAddressBookCreate())语句改为[selfaddressBook],尼玛重复代码不带这么玩的。。。

 

C代码   收藏代码
  1. + (NSArray *) contacts  
  2. {  
  3.     ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());  
  4.     NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);  
  5.     NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count];  
  6.     for (id person in thePeople)  
  7.         [array addObject:[ABContact contactWithRecord:(ABRecordRef)person]];  
  8.     [thePeople release];  
  9.     return array;  
  10. }  

 

 改为:

 

C代码   收藏代码
  1. + (NSArray *) contacts  
  2. {  
  3.     ABAddressBookRef addressBook = [self addressBook];  
  4.     NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);  
  5.     NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count];  
  6.     for (id person in thePeople)  
  7.         [array addObject:[ABContact contactWithRecord:(ABRecordRef)person]];  
  8.     [thePeople release];  
  9.     return array;  
  10. }  

 

 好,这丫的通讯录问题就解决了。

 

4、键盘中文输入后未关锁屏之后直接crash

这是个棘手的问题,因为我们根本不知道它到底哪儿出了问题,而且这个问题在以前iOS5等版本中都是好的。

这个问题的描述可以参看这个问题帖子:http://www.cocoachina.com/ask/questions/show/57585

在uitextview 或者 uitextfield里输入中文,键盘开着的状态下直接锁屏再开就会crash,里面也说道再系统设置、通用、还原、还原键盘字典就能解决问题,但能否从代码层面阻止这种crash

事实上中文输入在锁屏时会对用户输入的pinyin进行重置,而这部分在iOS6下会直接终止,导致crash,我们可以把它的运行放到后台的短进程里。可以这样做:

 

C代码   收藏代码
  1. - (void)applicationDidEnterBackground:(UIApplication *)application  
  2. {  
  3.     // ios6中文输入后锁屏之后就会crash,加上之后不会  
  4.     if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0))  
  5.     {  
  6.         if (!backgroundTask || backgroundTask == UIBackgroundTaskInvalid) {  
  7.             backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{  
  8.                 dispatch_async(dispatch_get_main_queue(), ^{  
  9.                     if (backgroundTask != UIBackgroundTaskInvalid)  
  10.                     {  
  11.                         [application endBackgroundTask:backgroundTask];  
  12.                         backgroundTask = UIBackgroundTaskInvalid;  
  13.                     }  
  14.                 });  
  15.             }];  
  16.         }  
  17.     }  
  18. }  

 

 上述代码是开一个后台task再在主线程里对它进行安全的endtask,这样就不会导致crash的问题了。

 

【2013.5.14更新】

5、关于sizeof线程安全的规避

在iOS6中对于NSString size计算会出现线程问题,例如下面代码如果dispatch到一个非主线程队列里,就很可能导致Crash

 

C代码   收藏代码
  1. letterSize = [c sizeWithFont:_contentFont];  

 我们需要采用下面的做法:

C代码   收藏代码
  1. NSAttributedString *attribStr =  [[[NSAttributedString alloc] initWithString:c attributes:[NSDictionary dictionaryWithObject:_contentFont forKey:NSFontAttributeName]] autorelease];  
  2. letterSize = [attribStr size];  

 但是上述方法只适用于iOS6,so

 

C代码   收藏代码
  1. CGSize letterSize;  
  2. if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)) {  
  3.     NSAttributedString *attribStr =  
  4.     [[[NSAttributedString alloc] initWithString:c  
  5.                                      attributes:[NSDictionary dictionaryWithObject:_contentFont  
  6.                                                                             forKey:NSFontAttributeName]]  
  7.      autorelease];  
  8.     letterSize = [attribStr size];  
  9. else {  
  10.     letterSize = [c sizeWithFont:_contentFont]; // 字符尺寸  
  11. }  

 

 

具体参照 http://stackoverflow.com/questions/12744558/uistringdrawing-methods-dont-seem-to-be-thread-safe-in-ios-6


原文地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值