With iOS 6 and Storyboards it is possible to create more advanced interactions which include your own navigational workflows which use your own view containers. With Flying Modals view controllers are embedded within an existing view controller at run-time by instantiating the view controller and attached view from the Storyboard and embedding it into the current view, allowing it to over the surface of the entire screen while being managed by a view controller dedicated to the model view.
Autolayout and constraints are now the norm and while they have been a challenge to learn they are becoming more useful all the time. Understanding Interface Builder within Xcode and Storyboards is half the effort. More on that later below...
We've worked in iOS with the Navigation Controller, Tab Bar Controller and the
simple modal for a while now and it is just not enough anymore. We can make it more
interesting. The Navigation Controller and Tab Bar Controller both containers for
other view controllers which manage a set of view controllers and their related
views. With iOS 5 there were new method in UIViewController for
addChildViewController and removeFromParentViewController which allow third
party developers to create our
own containers which allow our view controllers to work with the same lifecycle that
a view controller managed by a Navigation Controller would. This goes from loading
and appearing to orientation changes. With the addChildViewController and
removeFromParentViewController methods it is fairly easy to manage a container of
your own view controllers and views. Managing a simple modal which is displayed
and then dismissed is the easiest container and instead of presenting the usual
modal which covers the existing view completely instead of allowing the modal to
partially cover the current view to maintain the context of the current interaction
so the user does not feel they are leaving the current view to do something else,
which is not a good interaction for modals.
The new sharing Activities with UIActivitySheet are a good example of how modals
could be for an app. The text entry UI appears above the keyboard which appears
while the current view is still partially visible below.
The first flying modal covers the current view will a translucent mask before 2 boxes fly into the visible space from the left and right sides. The modal is dismissed with a button which is positioned at the bottom. The view which it covers is visible through this modal view. This sample is meant to show that the usual modal is not the only way to go. Sometimes a bit more interaction and movement can be done to make the workflow more interesting more function.
In this sample the blue box is on top while the red box is just below. It's possible that the red box could display controls for the modal while the top view shows a large text view or another sort of editor. The red box could also be moved out of view and replaced with another set of controls with a pan or swipe gesture.
The seconds modal also masks the current screen with a text view sliding down from the top. What makes this modal interesting is that automatically adapts for the 3.5" and 4" screens. This is done by using 2 constraints. The top constraint is used to first position the modal view out of view before animating it into the view. The other constraint is the height of the modal view which is set according to the height of the superview. Setting the height based on the superview the text view and other views within the modal view have constraints attached to the modal view so they are resized and repositioned accordingly. Managing these changes with the conventional frame position would take much more effort than simply adjustin the constant value of a couple of constraints.
What makes constraints so difficult is that they are automatically generated by Interface Builder in Xcode and you cannot just delete them. It is hard to select a constraint on the design surface so it is necessary browse the Size Inspector for all of the constraints related to the current context on the design surface. The constraints which are purple cannot be deleted while the ones which are blue can be deleted, but often you want to eliminate a constraint which cannot be deleted. When you first work with autolayout and constraints not being able to simply manage constraints is frustrating. Learning how to make a purpe constraint turn blue is what will make your work much easier.
Typically if you have a view which has a constraint attached to the top and bottom it will adjust the height of that view as the superview changes height. This is the right behavior when that is intended but sometimes it is not. To delete one of these constraints you must set the height value so that either the top or bottom constraint can be deleted. You are not allowed to create an ambiguous layout with Interface Builder, which is why constraints which are purple cannot be deleted. You must first add a constraint which is redundant so that the constraint that you want to delete is not longer necessary to prevent an ambiguous layout. After you've had some practice with it a while you will start to get the hang of it.
For critical constraints which are used in code to move views with animations
you will want to take steps to ensure these constraints are not accidentally lost
when working in Interface Builder. To manipulate the constraint an IBOutlet is
connected to the constraint and during viewDidLoad it helps to assert that the
IBOutlet is defined so when a constraint is accidentally detached it will be
noticed immediately. In the case of this project I defined a custom assertion
in the precompiled header (.pch) called MAAssert which works best for my
purposes. You may be find with simply using NSAssert. The main reason for using
MAAssert is that the NSAssert macro references self which becomes a problem
with ARC when using blocks which is common with Grand Central Dispatch which
is used commonly.
License: BSD
Brennan Stehling
SmallSharpTools
@smallsharptools (App.net)
@smallsharptools (Twitter)

