I am confused about how to program modular components for use with UIKit. According to the official documentation, ViewControllers seem to be the way to modularize UI components. So say I write a component as a ViewController. Now, how do I use this component within some view? Is there an official way to do this? All I can find is how to use a ViewController within other ViewControllers.
ViewController inside a View
In UIKit, there's a view hierarchy (parent and child views) which controls the geometry of view placement and layering on the screen. There also a view controller (VC) hierarchy (parent and child VCs) which controls the organization of your view controller logic.
Note that each VC is responsible for its own view, plus some number (possibly 0) of related auxiliary views that don't have their own VC. A child VC therefore becomes responsble for a "region" within the larger "region" controlled by its parent VC (where a region is the area occupied by the VC's collection of related views).
You set up the VC hierarchy in your storyboard (or in code if you prefer, but the storyboard is easier). In some standard cases, you're already doing this without thinking about it too much. For example, when you use a split VC, the UISplitViewController object is the parent, and there is a child VC for each split.
In custom cases, you use an IB convention to set up the relationship. For the parent VC, you add a "container view" item — either as that VC's view, or as a subview of that VC's view. (This is a separate item in the list of IB components from a normal "custom view".) You can then Control-drag from the container view to the child VC, to establish a "containment" segue between the parent and child VCs.
Note that there are methods you can override (will/didMove(toParentViewController:)) to customize what happens when VC hierarchies are set up or changed. There is some information here:
developer.apple.com/reference/uikit/uiviewcontroller
under the heading "Implementing a Container View Controller". There's also this older WWDC video:
developer.apple.com/videos/play/wwdc2012/236/
which lays out the philosopy behind this. The APIs might have been refined since 2012, so be careful about taking the sample code too literally, but this should be a good introduction to the design pattern that Apple had in mind.
Hi Quincey,
thank you for your detailed answer, but it does not really cover my question. I should say that I am only interested in programmatical solutions (no IB as I find the graphical interface just irritating and obfuscating). And my question basically is: How do I write a modular graphical component?
According to the official Apple documentation there seem to be 2 solutions to this:
1) Write a ViewController.
2) Write a View.
If you do 1), then how do you use your modular component in a setting where a view is required, for example within a StackView.
If you do 2), then how do you use your modular component in a setting where a viewcontroller is required, for example within a PageViewController.
It seems to me Apple messed up a few concepts here ...
>> How do I write a modular graphical component?
The question is too vague. There is no one thing that serves as a graphical component. There are views, controls and layers, all of which are interrelated, with choices about where to place different kinds of functionality.
View controllers are not graphical components. They are controllers in the MVC sense, which means they coordinate between a view (or set of views) and a data model. That means they tend to contain business logic related to views, and the often serve as delegates for view behavior. (The delegate pattern is another standard pattern.) The relationship is very flexible, though.
On iOS, it's usual to design a view controller hierarchy first, and then design the view structure that goes with each VC. (Each VC has its view, of course, but it may be responsible for others.)
If you want to do all this programmatically, then you're going to have to research the documentation a bit more thoroughly than is necessary for using storyboards in IB. You can find out quite a bit about VCs in the document I linked earlier:
developer.apple.com/reference/uikit/uiviewcontroller
In there, you will see that you create VC hierarchies programmatically using the "addChildViewController" method. There's also this:
developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/index.html
and a lot of documentation about UIView, such as:
developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/Introduction/Introduction.html
If you're interested in "modular" UI elements as opposed to graphical components generally, you may choose to create UIControl subclasses. (Switches, buttons, etc, are UIControl subclasses.) However, writing controls properly is typically harder than just putting drawing behavior in a UIView and business logic in a VC, so keep that in mind.
TBH you are making life much harder for yourself by avoiding IB, because it gives you a lot of standard behavior for free, and constrains what you can do to things that actually make sense. You can go programmatic if you want, but it's going to be a much tougher learning curve and conceptual load.