I started working as a iOS developer about a year and a half ago, and I'm having some trouble with software architecture and organization. I use Apple's recommended Model-View-Controller paradigm, and my code is generally very hierarchical: if a screen has (for example) a HUD, a control panel, and a display area, I have a main controller for the screen and sub-controllers for the HUD, control panel, and display area. The sub-controllers generally have no knowledge of their neighboring controllers and use methods in the main controller to interact with them.
However, especially in games, I often run into hierarchy-breaking problems that just can't be elegantly solved with this model. For instance, let's say I have a coin in the control panel area that I want to animate flying to the HUD. I can either animate the original coin to the new position, which would require a method like animateCoinToPosition: in the control panel sub-controller and a method like getPositionForFinalCoinPositionInHUD in the main controller; or, I can hide the original coin and create a duplicate coin either in the main controller or the HUD controller, which would require a delegate method like animateCoinToHUDFromStartingPosition:. I don't like having such oddly-specific methods in my controllers, since they only really exist to solve one problem, and additionally expose the hierarchy. My ideal solution would be to have a single method called animateCoinToHUD, but this would require flattening the entire hierarchy and merging the three controllers into one, which is obviously not worth it. (Or giving the sub-controllers access to their siblings — but that would essentially have the same effect. The sub-controllers would then have dependencies with each other, creating a single messy spiderweb controller instead of a main controller and three mostly independent sub-controllers.)
And it often gets worse. What if I want to display a full-screen animation or particle effect when moving the coin? What if my coin is a lot more complicated than a simple sprite, with many subviews and details, to the point where creating a duplicate coin using animateCoinToHUDFromStartingPosition: is inefficient? What if the coin flies to the HUD but then returns to the control panel? Do I "lend" the coin view to the main controller and then take it back when the animation completes, preserving the original position/z-order/etc. in temporary variables so that they can be restored? And another thing: logically, code that concerns multiple sub-controllers belongs in the main controller, but if these interactions are common, the main controller grows to be many thousands of lines long — which I've seen happen in many projects, not just my own.
Is there a consistent way to handle these hierarchy-breaking effects and actions that don't require duplicate code or assets, don't bloat my controllers, and elegantly allow me to share objects between sub-controllers? Or am I using the wrong approach entirely?