上次说到了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要低很多)
我们做兼容可以这样:
- -(void)viewDidLoad
- {
- singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
- [self.view addGestureRecognizer:singleTap];
- }
- -(void)handleSingleTap:(UITapGestureRecognizer*)gesture
- {
- if (gesture.state == UIGestureRecognizerStateEnded) {
- CGPoint tapPoint = [gesture locationInView:blackBackgroundView];
- if ((tapPoint.x > (ScreenWidth - 75) && tapPoint.y > (ScreenHeight - 75) && !isPhotoGif) || (tapPoint.x > (ScreenHeight - 75) && tapPoint.y > (ScreenWidth - 75) && !isPhotoGif)) {
- [self saveButtonPressed:nil];
- return;
- }
- }
上面对于tap手势的point进行判断再触发,而在ios6中则是直接绑定事件触发器
3、通讯录的隐私问题
iOS6中新增加了用户的隐私设置,所以在app需要访问用户的通讯录的时候需要用户允许。而以前广泛用的ABContact类库不包含这些东西。我们现在要对ABContact进行更改:
iOS中新增ABAddressBookCreateWithOptions方法我们要加入ABContact中,尼玛ABContact这货三年没更新了。。。
将原来getter方法:
- + (ABAddressBookRef) addressBook
- {
- return CFAutorelease(ABAddressBookCreate());
- }
改为:
- + (ABAddressBookRef) addressBook
- {
- ABAddressBookRef addressBook = nil;
- if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0)
- {
- addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
- //等待同意后向下执行
- dispatch_semaphore_t sema = dispatch_semaphore_create(0);
- ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
- {
- dispatch_semaphore_signal(sema);
- });
- dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
- dispatch_release(sema);
- }
- else
- {
- addressBook = ABAddressBookCreate();
- }
- return CFAutorelease(addressBook);
- }
上面的代码是一个需要用户同意的代码片段。
接着要对其余的CFAutorelease(ABAddressBookCreate())语句改为[self addressBook],尼玛重复代码不带这么玩的。。。
- + (NSArray *) contacts
- {
- ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate());
- NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
- NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count];
- for (id person in thePeople)
- [array addObject:[ABContact contactWithRecord:(ABRecordRef)person]];
- [thePeople release];
- return array;
- }
改为:
- + (NSArray *) contacts
- {
- ABAddressBookRef addressBook = [self addressBook];
- NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
- NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count];
- for (id person in thePeople)
- [array addObject:[ABContact contactWithRecord:(ABRecordRef)person]];
- [thePeople release];
- return array;
- }
好,这丫的通讯录问题就解决了。
4、键盘中文输入后未关锁屏之后直接crash
这是个棘手的问题,因为我们根本不知道它到底哪儿出了问题,而且这个问题在以前iOS5等版本中都是好的。
这个问题的描述可以参看这个问题帖子:http://www.cocoachina.com/ask/questions/show/57585
在uitextview 或者 uitextfield里输入中文,键盘开着的状态下直接锁屏再开就会crash,里面也说道再系统设置、通用、还原、还原键盘字典就能解决问题,但能否从代码层面阻止这种crash
事实上中文输入在锁屏时会对用户输入的pinyin进行重置,而这部分在iOS6下会直接终止,导致crash,我们可以把它的运行放到后台的短进程里。可以这样做:
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
- // ios6中文输入后锁屏之后就会crash,加上之后不会
- if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0))
- {
- if (!backgroundTask || backgroundTask == UIBackgroundTaskInvalid) {
- backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
- dispatch_async(dispatch_get_main_queue(), ^{
- if (backgroundTask != UIBackgroundTaskInvalid)
- {
- [application endBackgroundTask:backgroundTask];
- backgroundTask = UIBackgroundTaskInvalid;
- }
- });
- }];
- }
- }
- }
上述代码是开一个后台task再在主线程里对它进行安全的endtask,这样就不会导致crash的问题了。