15

我正在UIPresentationController为我的视图控制器转向基于演示文稿,但对 API 感到有些困惑。

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

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

在 Resizable 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是否可以在更精细的级别上执行自适应演示?

4

3 回答 3

1

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

不容易。

我建议以下选项之一:

  1. 放弃控制并接受 UIKit 有限的适应性:您可以更改为全屏演示或为特定的 trait 集合呈现不同的视图控制器。使用它可以更快地发布您的应用程序。

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

  3. 使用视图控制器包含。这是你在坚持 UIKit 最佳实践时可以达到的最低水平。您的主视图控制器成为容器视图控制器的子级,而不是呈现您要求容器显示另一个视图控制器。如果应用程序应该是定制的和精致的,那就去吧,你可以花时间让它恰到好处。

于 2015-08-18T15:13:09.667 回答
1

采用:

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

即使尺寸类没有改变,它也会被调用旋转,所以它是一个进行习惯用法/方向特定适应的好地方。请记住,iPhone 6 可以在放大模式下运行。

于 2016-03-05T03:18:23.450 回答
0

我遇到了同样的问题。可以从尺寸类中解释设备方向,尽管并非完全明确,但以下内容适用于我的目的。

来自Programming iOS 9: Dive Deep into Views, View Controllers and Frameworks,一本很好的书,里面有很多重要的细节,比如:

horizontalSizeClass,verticalSizeClass

一个UIUserInterfaceSizeClass值,要么.Regular要么.Compact。这些被称为尺寸等级尺寸等级组合起来具有以下含义:

垂直和水平尺寸类别都是.Regular:我们在 iPad 上运行

垂直尺寸类是.Regular,但水平尺寸类是.Compact:我们在 iPhone 上运行,应用程序是纵向的。(或者,我们可能在 iPad 上以分屏 iPad 多任务配置运行;请参阅第 9 章)。

垂直和水平尺寸类都是.Compact:我们在 iPhone(iPhone 6 plus 除外)上运行,应用程序是横向的。

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

例如在视图控制器中:

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
    }
}
于 2016-04-08T04:12:52.603 回答