基于视图大小的自适应UIPresentationController

时间:2015-04-09 13:28:30

标签: iphone ios8 adaptive-ui uipresentationcontroller uitraitcollection

我正在为我的视图控制器转移到基于UIPresentationController的演示文稿,但与API有些混淆。

我有一个自定义侧边栏样式视图控制器演示文稿(类似于LookInside WWDC 2014演示代码)。

此类集群(UIPresentationControllerUIViewControllerTransitioningDelegateUIViewControllerAnimatedTransitioning)在常规大小类视图中将视图控制器显示为屏幕边缘的侧边栏,并呈现相同的视图控制器在紧凑大小的类视图上全屏显示。

在可调整大小的iPad目标上进行测试显示正确的行为:我将水平尺寸类设置为“紧凑”,我的视图控制器从侧边栏切换到全屏。

但是,我想要更多粒度。当设备处于横向时,我想在iPhone 6和6+上使用侧边栏式视图控制器演示,并且纵向使用所有iPhone的全屏风格演示。

所以在我的方法中

- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

我实现了一些逻辑来检测侧边栏是否会占用太多屏幕,假设我使用以下条件:

//If my sidebar is going to occupy more than half the new width of the view...
if( self.sidebarTransitionController.width > size.width / 2.0 )
{
    //Override the presentation controller's trait collection with Compact horizontal size class
    sidebarPresentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
}
else
{
    //Otherwise override the trait collection with Regular
    sidebarPresentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];

}

然而,这没有任何作用。 UIPresentationController.overrideTraitCollection州的文档:

  

使用此属性指定要应用于呈现和呈现视图控制器的任何特征。您指定的特征会覆盖当前对视图控制器有效的任何现有特征。此属性的默认值为nil。

     

为此属性指定新值会导致表示控制器转换为新的特征集,这可能会导致显示所显示界面的动画。

将新值分配给演示控制器不会导致我呈现的界面以任何方式更改。 (即使我在overrideTraitCollection对象中创建UIPresentationController时分配了UIViewControllerTransitioningDelegate

我错过了什么?是否可以在更细粒度的级别上使用UIPresentationController执行自适应演示?

3 个答案:

答案 0 :(得分:1)

  

是否可以在更细粒度的级别上使用UIPresentationController执行自适应演示?

不容易。

我建议使用以下选项之一:

  1. 放弃控制并接受UIKit有限的适应性:您可以更改为全屏演示或为特定特征集合提供不同的视图控制器。使用此功能可以更快地发送您的应用。

  2. 使用演示文稿但对UIKit起作用。一种方法是覆盖viewWillTransitionToSize:withTransitionCoordinator:并关闭然后重新呈现呈现的视图控制器,进行所需的任何更改,例如提供不同的演示样式或演示控制器。这可以在不花太多时间的情况下给出好的结果。

  3. 使用视图控制器包含。这是您在坚持使用UIKit最佳实践时可以达到的最低级别。您的主视图控制器成为容器视图控制器的子项,而不是呈现您要求容器显示其他视图控制器。如果应用程序应该是自定义和精致的,那么请使用此功能,并且您可以花时间将其做得恰到好处。

答案 1 :(得分:1)

使用:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
                                                               traitCollection:(UITraitCollection *)traitCollection NS_AVAILABLE_IOS(8_3);

即使大小等级没有改变,它也会被要求轮换,所以这是一个习惯性/定向特定适应的好地方。请记住,iPhone 6可以在放大模式下运行。

答案 2 :(得分:0)

我遇到了同样的问题。可以从大小类中解释设备方向,虽然不是完全明确的,但以下方法适用于我的目的。

来自Programming iOS 9: Dive Deep into Views, View Controllers and Frameworks,这是一本很好的书,里面写着这样重要的细节:

  

horizontalSizeClassverticalSizeClass

     

UIUserInterfaceSizeClass值,.Regular.Compact。这些被称为大小类 大小类组合起来具有以下含义:

     

纵向和横向尺寸类别均为.Regular:我们在iPad上运行

     

垂直尺寸等级为.Regular,但横向尺寸等级为.Compact:我们在应用程序纵向移动的iPhone上运行。 (或者,我们可能会在iPad上以分离式iPad多任务配置运行;请参阅第9章。)

     

纵向和横向尺寸类别均为.Compact:我们正在iPhone(iPhone 6 plus除外)上运行,应用程序横向显示。

     

垂直尺寸等级为.Compact,水平尺寸等级为.Regular:我们在横向展示的iPhone 6上运行。

e.g。在视图控制器中:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowComposeView" {
        segue.destinationViewController.presentationController!.delegate = self
        segue.destinationViewController.modalPresentationStyle = .PageSheet
    }
}

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    // If we do an adaptive presentation, and adapt from Page Sheet to Form Sheet,
    // then on iPhone 6 we will get the nice rounded corners of the nav bar 
    // in both portrait and landscape. (From pg. 298 of Programming iOS 9)

    // We want this behaviour on iPhone in Portrait orientation only.
    if traitCollection.horizontalSizeClass == .Compact && traitCollection.verticalSizeClass == .Regular {
        return .FormSheet
    }
    else {
        return .PageSheet
    }
}
相关问题