--- 以上对xcode10及以前模拟器都没问题 ---
成都创新互联公司专注于江油企业网站建设,成都响应式网站建设公司,商城网站制作。江油网站建设公司,为江油等地区提供建站服务。全流程按需定制网站,专业设计,全程项目跟踪,成都创新互联公司专业和态度为您提供的服务
那么 xCode11 iOS 13 针对modalStyle推出了新特性,presentViewController的时候需要强制添加fullScreen的modalStyle,就会导致在横屏切换到竖屏的过程中出现一个诡异的抖动,那么问题来了,fullScreen到底做了什么,和之前的present 有和区别呢
这篇文章写的还是挺详细的
A-B 的情况下,用fullScreen的话 会调用presentedViewController的viewlayoutsubviews导致重新布局 有一个切换 闪一下
这里有两个方案
fullScreen模式下 在页面A里拦截一下这种情况下 拦截一下页面
使用overFullScreen 模式,但这个模式在横竖屏下会引发一系列连锁反应,系统不会帮你强制竖屏,当你presentingViewcontroller里实现了
相关代理之后,他能够根据当前window来实现页面的横竖屏转换,到这里 ,如果你的需求已经满足了,那么恭喜你,你已经成功了。下面内容可以忽略了~
因为用到了键盘和UIMenuController,而这两个东西并不在当前 application的keywindow上,下面可以看到,而我们要用到的键盘和Menu其实都是依附于UITextEffectsWindow上的
当我们使用overFullScreent的style,横屏进入页面的时候,系统其实并不会将 UITextEffectsWindow 这个window自动旋转为竖屏,系统判定当前仍然是横屏,name键盘和menu仍然是按照横屏的高度去计算的,这就会有问题,针对这种case,目前用了一个比较迂回(一个坑一个坑去填)的解决办法。
以上希望能够帮助到有需要的朋友,有问题进一步沟通~
在开发项目的时候,遇到了一个问题,就是其中一个页面需要强制横屏,而其他页面要强制竖屏,然后返回在回到横屏,总结了一些人的经验给需要的人。
首先在AppDelegate.h里面添加@property(nonatomic,assign)NSInteger allowOrientations; 然后实现下面的方法。
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow(UIWindow*)window{
if(_allowOrientations ==1) {
return UIInterfaceOrientationMaskLandscapeRight;
}
else{
return (UIInterfaceOrientationMaskPortrait);
}
}
最后在需要使用横竖屏切换的控制器导入Appdelegate.h文件 实现方法:
- (void)viewDidLoad{
[superviewDidLoad];
AppDelegate * appDelegate = (AppDelegate *)[UIApplicationsharedApplication].delegate;
appDelegate.allowRotation =1;
}
返回到上一个页面自动切换到竖屏:
if([[UIDevicecurrentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector =NSSelectorFromString(@"setOrientation:");
NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector];
[invocation setTarget:[UIDevicecurrentDevice]];
intval =UIInterfaceOrientationPortrait;
[invocation setArgument:val atIndex:2];
[invocation invoke];
}
在你想支持横竖屏的viewController里面重写两个方法:
1
2
3
4
5
6
7
8
9
10
11
// 支持设备自动旋转
- (BOOL)shouldAutorotate
{
return YES;
}
// 支持横竖屏显示
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
这样在这个viewController中就可以横竖屏切换了。
注意如果你window的rootViewController是一个navigationController,可能会出现以下问题:
你的navigationController只支持竖屏,但是你push到了某个新的controller中,这个controller支持横竖屏,当你在新的controller中切换到横屏后(也有可能在切换到横屏然后pop回来后),这时候程序会闪退,因为你的navigationController不支持横屏。
如果你想解决这个问题,就需要自己写一个UINavigationController的子类,在这个类中重写方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (BOOL)shouldAutorotate
{
return [self.viewControllers.lastObject shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.viewControllers.lastObject supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];
}
然后用这个类去创建实例作为window的rootViewController,这样就可以避免这个问题了。
前提: APP全局强制竖屏且不支持横屏!在部分页面如果打开横竖屏开关,则支持横竖屏动态切换;如果关闭,则需要点击才能跳转横屏页面。
设备在控制页面打开横竖屏开关,即设备支持横竖屏动态切换。
下图做了个简单的gif展现,下图的操作是操作手机横竖屏的结果
下面说一下强制横屏的处理办法
强制横屏就是在设备仅支持竖屏的前提下
那么问题来了,既然有两处都可以设置,那么最终取值以哪一个为准呢?
通过测试发现,如果两处都设置了,最终以第二种设置为(主要)判断依据;如果第二处未设置,则以第一处为准。
只有当前window支持某个方向的旋转,才能对控制器(如UIviewcontroller)进行相应方向的旋转并达到想要的效果(内容跟着转动)。
设置了可旋转的方向之后,就要对个别控制器做更细致的限制了,比如想让A控制只能竖屏,或者让B控制器只能横屏,就需要用到VC的扩展方法(系统自带的)
通过创建一个新项目,页面布局如下:
分别自定义了UINavigationcontroller和UIviewcontroller,并重写了vc旋转相关的三个扩展方法,将UINavigationcontroller设置为window的rootviewcontroller
直接启动APP查看旋转方法调用情况如下:
通过以上打印结果可以看出,APP启动时,调用顺序为APPdelegate的application:supportedInterfaceOrientationsForWindow: - nav的supportedInterfaceOrientations - nav的shouldAutorotate - vc的supportedInterfaceOrientations
通过以上结果论证得出结论:APP在监听到旋转时,会首先通知window 并执行delegate中的supportedInterfaceOrientationsForWindow方法,然后通知rootviewcontroller并执行supportedInterfaceOrientations方法,最后通知栈顶vc并执行supportedInterfaceOrientations。
以上例子我们发现只调用了nav的shouldAutorotate,而栈顶vc的shouldAutorotate方法被忽略了,或许我们可以猜测出,是否能够旋转取决于vc的父容器即nav。
此时,我们手动旋转模拟器,看看打印结果如何?
通过以上打印结果可以看出,手动旋转APP时,调用顺序为APPdelegate的application:supportedInterfaceOrientationsForWindow: - nav的supportedInterfaceOrientations - nav的shouldAutorotate
即使,手动旋转手机,也没有调用vc的shouldAutorotate方法,甚至连vc的supportedInterfaceOrientations方法都没有调用,
为了进一步验证猜想,我们点击push按钮,跳转到另一个只允许横屏的自定义vc(LandscapeRightVC),打印结果如下:
通过打印可以看到只调用了LandscapeRightVC的旋转方向的方法,而supportedInterfaceOrientations、shouldAutorotate方法均未调用,但屏幕方向确实已经横屏了,之所以能够横屏时因为此时nav支持横屏方向,进一步验证了以上观点。
我们再将当前nav设置为只支持竖屏,并且点击present按钮,跳转到只支持横屏的vc看看打印情况:
执行顺序大致是:
[AppDelegate application:supportedInterfaceOrientationsForWindow:] -
[NavVC supportedInterfaceOrientations] -
[LandscapeRightVC preferredInterfaceOrientationForPresentation] -
[LandscapeRightVC supportedInterfaceOrientations] -
[NavVC shouldAutorotate] -
[LandscapeRightVC shouldAutorotate] -
[LandscapeRightVC supportedInterfaceOrientations]
那么对于一个项目中个别页面需要横屏时,我们大致可以进行如下写法:
假如将rootviewcontroller设置为tabbar,并将tabbar设置为只支持竖屏,而将其中一个item设置为LandscapeRightVC,打印结果如下:
顺便提一提UIDeviceOrientation(设备方向)和UIInterfaceOrientation(UI方向)的区别
售后响应及时
7×24小时客服热线数据备份
更安全、更高效、更稳定价格公道精准
项目经理精准报价不弄虚作假合作无风险
重合同讲信誉,无效全额退款