CustomIOS7AlertView 适配 iOS 8
来源:互联网 发布:千里眼淘宝版下载 编辑:程序博客网 时间:2024/05/17 04:46
原来项目中用到一个很好用的自定义对话框 CustomIOS7AlertVIew
这个对话框在iOS 7下完全没有问题。
self.alertView = [[CustomIOS7AlertView alloc] init]; self.alertView.delegate = self; self.dvController = [[ZYAlertDirectionalVersionViewController alloc] initWithNibName:@"ZYAlertDirectionalVersion" bundle:[NSBundle mainBundle]]; self.dvController.delegate = self; self.dvController.view.layer.cornerRadius = 8; [self.alertView setButtonTitles:[NSMutableArray arrayWithObjects: nil]]; [self.alertView setContainerView:self.dvController.view]; [self.alertView show];
使用方法很简单。视图是在xib里面的,使用setContainerView放入CustomIOS7AlertView里面就可以了。横竖屏也可以适应。
但是在iOS 8中,横屏的时候,弹出的框确实竖屏的样子。
查了资料后,才知道,原来是iOS 8 中UIScreen的方向与实际方向同步了,而不是iOS7中一直竖屏。所以iOS7中做了交换width、height的动作,而iOS 8中就多余了。
摘录一段:
Yes, it's orientation-dependent in iOS8, not a bug. You could review session 214 from WWDC 2014 for more info: "View Controller Advancements in iOS 8"
Quote from the presentation:
UIScreen is now interface oriented:
- [UIScreen bounds] now interface-oriented
- [UIScreen applicationFrame] now interface-oriented
- Status bar frame notifications are interface-oriented
- Keyboard frame notifications are interface-oriented
CustomIOS7AlertView中有四个地方需要修改:
1. 创建containerView的时候,计算屏幕大小。 8.0以上不需要交换高宽。
// Helper function: count and return the screen's size- (CGSize)countScreenSize{ if (buttonTitles!=NULL && [buttonTitles count] > 0) { buttonHeight = kCustomIOS7AlertViewDefaultButtonHeight; buttonSpacerHeight = kCustomIOS7AlertViewDefaultButtonSpacerHeight; } else { buttonHeight = 0; buttonSpacerHeight = 0; } CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; //2015-1-27 dinghongyan 8.0以上适配。不转,屏幕大小对应屏幕方向。 if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { CGFloat tmp = screenWidth; screenWidth = screenHeight; screenHeight = tmp; } } return CGSizeMake(screenWidth, screenHeight);}
2. show的时候,添加到window上,不需要根据方向,在代码中转换。
// Create the dialog view, and animate opening the dialog- (void)show{ dialogView = [self createContainerView]; dialogView.layer.shouldRasterize = YES; dialogView.layer.rasterizationScale = [[UIScreen mainScreen] scale]; self.layer.shouldRasterize = YES; self.layer.rasterizationScale = [[UIScreen mainScreen] scale];#if (defined(__IPHONE_7_0)) if (useMotionEffects) { [self applyMotionEffects]; }#endif dialogView.layer.opacity = 0.5f; dialogView.layer.transform = CATransform3DMakeScale(1.3f, 1.3f, 1.0); self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0]; [self addSubview:dialogView]; // Can be attached to a view or to the top most window // Attached to a view: if (parentView != NULL) { [parentView addSubview:self]; // Attached to the top most window (make sure we are using the right orientation): } else { //2015-1-27 dinghongyan 8.0以上适配。不转。会自适应当前方向。 if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: self.transform = CGAffineTransformMakeRotation(M_PI * 270.0 / 180.0); break; case UIInterfaceOrientationLandscapeRight: self.transform = CGAffineTransformMakeRotation(M_PI * 90.0 / 180.0); break; case UIInterfaceOrientationPortraitUpsideDown: self.transform = CGAffineTransformMakeRotation(M_PI * 180.0 / 180.0); break; default: break; } } [self setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; [[[[UIApplication sharedApplication] windows] firstObject] addSubview:self]; } [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4f]; dialogView.layer.opacity = 1.0f; dialogView.layer.transform = CATransform3DMakeScale(1, 1, 1); } completion:NULL ];}
3. 键盘弹出事件中,横屏不需要交换高宽
// Handle keyboard show/hide changes- (void)keyboardWillShow: (NSNotification *)notification{ CGSize screenSize = [self countScreenSize]; CGSize dialogSize = [self countDialogSize]; CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; //2015-1-29 dinghongyan iOS8适配。 if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { CGFloat tmp = keyboardSize.height; keyboardSize.height = keyboardSize.width; keyboardSize.width = tmp; } } [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{ dialogView.frame = CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - keyboardSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height); } completion:nil ];}
4. 转屏的时候,不要代码中强制转。因为转屏的时候,原来的代码是整个dialogView旋转的,所以底层的View旋转了,上层的containerView和我自定义的view都转了。
实际上,底层的View转不转都无所谓的,不转的话,frame要调整。而上层的containerView和自定义的view是不需要转的。
所以,索性不使用旋转,而是改变底层view的frame。
// Handle device orientation changes- (void)deviceOrientationDidChange: (NSNotification *)notification{ // If dialog is attached to the parent view, it probably wants to handle the orientation change itself if (parentView != NULL) { return; } if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; CGAffineTransform rotation = [self changeOrientation]; [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{ dialogView.transform = rotation; } completion:^(BOOL finished){ // fix errors caused by being rotated one too many times dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ UIInterfaceOrientation endInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if (interfaceOrientation != endInterfaceOrientation) { dialogView.transform = [self changeOrientation]; } }); } ]; }else{ //2015-1-27 dinghongyan 8.0以上适配。不转,改frame [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{ self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); dialogView.center = self.center; } completion:^(BOOL finished){ UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; // fix errors caused by being rotated one too many times dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ UIInterfaceOrientation endInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if (interfaceOrientation != endInterfaceOrientation) { //如果转屏失败,再转回去 self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); dialogView.center = self.center; } }); } ]; }}//iOS7中转屏处理-(CGAffineTransform)changeOrientation{ UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; CGFloat startRotation = [[self valueForKeyPath:@"layer.transform.rotation.z"] floatValue]; CGAffineTransform rotation; switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 270.0 / 180.0); break; case UIInterfaceOrientationLandscapeRight: rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 90.0 / 180.0); break; case UIInterfaceOrientationPortraitUpsideDown: rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 180.0 / 180.0); break; default: rotation = CGAffineTransformMakeRotation(-startRotation + 0.0); break; } return rotation;}
5. 这个应该是ps了。跟适配没有关系,但是是CustomIOS7AlertView提醒我要注意的一个地方。
就是转屏失败怎么办?
原来的代码,在转屏失败的时候,很萌的来了一句TODO
UIInterfaceOrientation endInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if (interfaceOrientation != endInterfaceOrientation) { // TODO user moved phone again before than animation ended: rotation animation can introduce errors here }
如果按照旋转角度的话,其实我拎不清的。左转右转、多少度神马的,转不过弯儿来。但是改frame的话,就好做多了。只要失败的时候,再根据当前的屏幕重新调整一次就好了。于是:
//2015-1-27 dinghongyan 8.0以上适配。不转,改frame [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{ self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); dialogView.center = self.center; } completion:^(BOOL finished){ UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; // fix errors caused by being rotated one too many times dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ UIInterfaceOrientation endInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if (interfaceOrientation != endInterfaceOrientation) { //如果转屏失败,再转回去 self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); dialogView.center = self.center; } }); } ];
至此,大功告成!
- CustomIOS7AlertView 适配 iOS 8
- 关于iOS 7以后自定义UIAlertview(CustomIOS7AlertView)的用法心得
- iOS 7以后自定义UIAlertview(CustomIOS7AlertView)的用法
- CustomIOS7AlertView.m死机问题修改
- 适配iOS 8备忘录
- 适配iOS 8备忘录
- 适配iOS 8备忘录
- 适配iOS 8
- 适配iOS 8
- iOS开发--适配iOS 10以及Xcode 8
- iOS开发--适配iOS 10以及Xcode 8
- iOS开发--适配iOS 10以及Xcode 8
- ios适配
- IOS适配
- iOS适配
- iOS适配
- ios 适配
- iOS 适配
- cocos2dx 中实现再按一次退出效果
- 杭电ACM-The Snail
- 11种经典软件滤波的原理
- C++:函数————函数重载与函数模板
- docker命令之build
- CustomIOS7AlertView 适配 iOS 8
- CentOS集群自动同步时间的一种方法
- Using R — Calling C Code ‘Hello World!’
- Apache (支持IPv6) 安装及常见错误
- log4j:WARN No appenders could be found for logger
- Google 地理信息反解析
- 实现HTTP断点续传下载工具(附源代码)
- Can not perform this action after onSaveInstanceState
- 互联网创业准备