可调整大小的容器视图包含视图控制

时间:2015-04-08 13:48:44

标签: ios objective-c uiviewcontroller uicontainerview

我希望能够在屏幕上同时显示多个UIViewControllers,按照下图所示排列为窗格。 能够:

  • 在程序运行时添加其他窗格。
  • 拖动窗格之间的条形以调整它们的大小

我在考虑使用容器视图(它们只是视图控制器?)

我最好如何做到这一点?

        ┌───────────────────┳────────────────────────────┐
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        ┣━━━━━━━━━━━━━━━━━━━┫                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        │                   ┃                            │
        └───────────────────┻────────────────────────────┘

5 个答案:

答案 0 :(得分:12)

我创建了一个快速原型来演示如何做到这一点:https://github.com/MrNickBarker/iOSAccordionPanels/tree/master

enter image description here

我将在这里解释一下本质。您可以查看仓库中的详细信息。

  • 所有面板和分隔符都受约束尾随导致彼此
  • 分隔符彼此约束(尾随到前导),第一个分隔符被约束到超级视图的前端
  • 每个分隔符都将对其约束的引用保存到前一个分隔符,并使用平移手势
  • 更新该约束常量
  • 面板具有最小宽度约束。不是严格需要但看起来不错。
  • 分隔符约束具有较低的优先级(例如999),因此它们尊重面板的最小宽度,如果有更多空间,面板也会产生很好的效果
  • 添加或删除面板时,请删除约束并再次为所有面板和分隔符添加约束。可以改进这一点以保留现有面板或动画的大小。

这是一张粗略的图表:

superview-panel-separator-panel-separator-panel-superview
superview-------separator-------separator

答案 1 :(得分:4)

我不会使用storyboard的ContainerViewController。当您已经知道屏幕中需要多少个控制器时,它们更适合在故事板上使用。您想要在代码中动态添加删除控制器。

首先实现一个处理普通视图(窗格)的控制器。在添加/删除新窗格时,将所有逻辑放在其中,可以添加窗格,删除窗格并在场景视图中调整其大小。我也不会使用约束,会变得太复杂。添加窗格时,您必须知道视图的两侧是什么,抓住它们并为其添加约束。删除窗格时,您还必须删除某些窗格的约束(不是全部)。很多。

但是,如果您使用框架,则可以构建一个采用容器宽度和高度的方程式,并重新计算所有视图的框架。

一旦你有了工作,只需将控制器添加到这些窗格(视图)中,如:

//Here self would be the containerController and paneContainer one of the pane views
UIViewController *newPaneVC = [UIViewController new];
newPaneVC.view.frame = [self calculateFrameForNewPane];
[self.paneContainer addSubview:newPaneVC.view];
[self addChildViewController:newPaneVC];
[newPaneVC didMoveToParentViewController:self];

//Add resizing masks to make sure new VC resizes with superview changes (example: when more panes are added/removed)
[newPaneVC.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];

最后,看一下这个库: https://github.com/yatsu/treemapkit

它是在3年前完成的,但我在一个项目中使用它并且运行良好。它为您提供了基于值数组在屏幕上绘制不同大小视图的所有逻辑。您可以使用此方法添加和删除窗格,并使用委托返回已添加控制器的单元格(窗格)。

答案 2 :(得分:2)

我在单独的xib中设置每个视图+约束,并使用Masonry在代码中为视图之间的约束创建简单的AutoLayouting约束。

答案 3 :(得分:2)

我会有一个ViewController负责管理你要添加的视图控制器并调整其大小。

然后,我将视图控制器及其视图添加到该主视图控制器中。

所以,你需要注意几件事情:

  • 如果使用自动布局,则需要使用约束从视图控制器添加视图,因此当大小更改时,视图内容也会更改。
  • 如果您不使用自动布局,则可能需要在尺寸更改时进行一些更改,您可以在viewDidLayoutSubviews中执行此操作
  • 如果您需要调整tableviews / collectionviews的大小,也可以使用viewDidLayoutSubViews

答案 4 :(得分:2)

一个简单的解决方案是创建和管理由单个ViewController管理的UIView。您可以使用Auto Layout的宽高比工具调整大小,从而实现各种尺寸和平铺效果。要创建新的图块,您可以在设定的间隔之间获得一个随机数,以获得不同的尺寸。