I want to be able have several UIViewControllers on the screen at once, arranged as panes, as per the diagram below. With the ability to:
I was thinking of using container views (which are just view controllers?)
How would I best achieve this?
┌───────────────────┳────────────────────────────┐
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
┣━━━━━━━━━━━━━━━━━━━┫ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
│ ┃ │
└───────────────────┻────────────────────────────┘
I have created a quick prototype to demonstrate how this can be done: https://github.com/MrNickBarker/iOSAccordionPanels/tree/master
I'll explain the essence here. You can check the details in the repo.
Here is a crude diagram:
superview-panel-separator-panel-separator-panel-superview
superview-------separator-------separator
I would not use storyboard´s ContainerViewController. Those are more designed to be used on storyboards when you already know how many controllers need to be in the screen. You instead want to add remove controllers dynamically in code.
First implement a controller that handles plain views (panes). Put all your logic in there be able to add a pane, remove it and resize already in place views when a new pane is added/removed. I wouldn't use constraints either, is going to be too complicated. When you add a pane you would have to know what view's sides are surrounding it, grab them and add constraints to it. When removing a pane, you would have to remove also some constraint (not all) of certain panes..too much.
However if you use frames you can just build an equation that takes the width and height of the container and recalculates all view's frames.
Once you have that working, just add controllers into those panes (views) like:
//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];
Lastly, take a look at this library: https://github.com/yatsu/treemapkit
It was done 3 years ago but I used it in a project and worked well. It gives you all logic to draw views with different sizes on the screen based on an array of values. You add and remove panes with this and use the delegates to return cells (panes) with controller already added.
I'd setup each view + constraints in a separate xib and use Masonry for creating easy AutoLayouting constraints in code for the constraints between the views.
I would have a ViewController that was responsible for managing and resizing the view controllers you would add.
Then, I would add view controllers and their views into that main view controller.
So, a couple of things you need to pay attention to:
An easy solution would be to create and manage UIViews that are in turn managed by a single ViewController. You could achieve the various sizes and tiled effect by using Auto Layout's aspect ratio tool for resizing. To create new tiles you could get a random number between a set interval to get different sizes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With