基于视图大小的自适应UIPresentationController

15

我转向使用基于UIPresentationController的视图控制器演示,但遇到了一些API方面的困惑。

我有一个自定义的侧边栏样式视图控制器呈现(类似于LookInside WWDC 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。

将此属性赋予新值会导致呈现控制器转换到新的特征集合,这可能会导致呈现界面的动画。

将新值分配给呈现控制器不会以任何方式改变我呈现的界面。(即使在从UIViewControllerTransitioningDelegate对象内创建UIPresentationController时分配了overrideTraitCollection。)

我错过了什么?是否可能在更细粒度的层面上使用UIPresentationController执行自适应呈现?

3个回答

2
可以使用UIPresentationController在更精细的层面上执行自适应演示吗?
不容易。
我建议采用以下其中一种方案:
1. 放弃控制并接受UIKit的有限适应性:您可以更改为全屏演示或针对特定特征集呈现不同的视图控制器。这样做可以更快地发布应用程序。 2. 使用演示,但与UIKit相反。一种方法是重写viewWillTransitionToSize:withTransitionCoordinator:并解除再呈现所展示的视图控制器,进行任何想要的更改,例如提供不同的呈现样式或呈现控制器。这可能会在不花费太多时间的情况下产生可行的结果。 3. 使用视图控制器包含。这是在坚持UIKit最佳实践的同时可以达到的最低级别。您的主视图控制器变成了容器视图控制器的子级,而不是呈现,您要求容器显示其他视图控制器。如果应用程序应该是自定义和精美的,并且您可以花时间让它完美,那么就采用此方法。

1

使用:

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

即使尺寸类别没有改变,也会调用旋转函数,因此这是进行习语/方向特定适应的好地方。请记住,iPhone 6 可以在缩放模式下运行。

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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接