You Can’t Avoid Complexity, but You Can Make It Easier to Deal with
As a project nears completion, it’s the time the value of earlier decisions becomes apparent. Because the project was tightly scoped, and because of some early planning to avoid potential pain points, I’m happy with how the bits are fitting together, and the general level of complexity in the app.
The best example of this is a view with a huge amount of layout going on. Rather than building a series of child view controllers to handle each section, the whole view is a collection view with a custom layout. To manage the complexity of switching between multiple layouts, the collection view layout is built from a series of sub-layouts on a per-section basis, allowing table like behavior, horizontal flow with wrapping, and stacked cards to all live in one view controller.
This means all of the layout is determined by the collection layouts, several of which support autosizing based on cell contents and screen size. The data is handled by a view model, which then passes configuration objects into the collection cells, which handle their own layout and presentation.
There are several places where it could be even cleaner, particularly more separation of view and view controller code, breaking sections of the app into frameworks, and so on, but this code looks like it will be maintainable in the long term.