After attempting many different solutions to get around this extremely annoying bug, I've found one method that works (it is certainly not a "fix", but a workaround).
Lock controllers when you're done with them.
Select a view controller in a storyboard, open the Identity inspector, and at the bottom in the Document section, you'll see a Lock dropdown. Select "All Properties" from the lock drop down.
If you do this for all of the controllers giving you issues (or just all of the controllers in general, even), you'll notice when you open the storyboard, Xcode will still modify the frames of various elements, but then immediately undo the changes.
This then leads to the development cycle being:
- Unlock a view controller
- Perform any necessary changes
- Lock the view controller
- Commit
Locking also works on a view-by-view case if that suits your needs better.
The bug has been around for quite some time now and it doesn't appear to be getting fixed any time soon, so unfortunately this will have to suffice for now.