0
votes

I have a Storyboard which I mainly use to configure a few modal view controllers with their accompanying UINavigationControllers and UITableViewCells.

My app is a Universal app, so I want to support both iPhone and iPad. The additional storyboards I use for the modal view controllers, however, are not specific to any device (thanks to AutoLayout), so I could just use them in both.

Currently I load the initial view controller of a Storyboard programmatically like this:

UIStoryboard *companyStoryboard = [UIStoryboard storyboardWithName:@"CompanySelection" bundle:nil];

I created the CompanySelection.xib choosing "iPad" when asked by Xcode what device I would like to create the Storyboard for. So it works fine when running on an iPad. However, it crashes on an iPhone:

2014-06-24 16:13:01.720 Notes[24630:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'CompanySelection' in bundle NSBundle </path/to/library/Application Support/iPhone Simulator/7.1-64/Applications/E78E3994-0147-4BD5-AAB6-EA452707EC4D/MyApp.app> (loaded)'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000102dd7495 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000102b3699e objc_exception_throw + 43
    2   UIKit                               0x0000000101d6c2b7 +[UIStoryboard storyboardWithName:bundle:] + 542
    3   Notes                               0x000000010007f652 -[GRMasterViewController insertNewObject:] + 210 // the call which loads a view controller from a storyboard and should display it modally
    4   UIKit                               0x00000001018b3f06 -[UIApplication sendAction:to:from:forEvent:] + 80
    5   UIKit                               0x00000001018b3f06 -[UIApplication sendAction:to:from:forEvent:] + 80
    6   UIKit                               0x00000001018b3eb4 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 17
    7   UIKit                               0x0000000101990880 -[UIControl _sendActionsForEvents:withEvent:] + 203
    8   UIKit                               0x000000010198fdc0 -[UIControl touchesEnded:withEvent:] + 530
    9   UIKit                               0x00000001018ead05 -[UIWindow _sendTouchesForEvent:] + 701
    10  UIKit                               0x00000001018eb6e4 -[UIWindow sendEvent:] + 925
    11  UIKit                               0x00000001018c329a -[UIApplication sendEvent:] + 211
    12  UIKit                               0x00000001018b0aed _UIApplicationHandleEventQueue + 9579
    13  CoreFoundation                      0x0000000102d66d21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    14  CoreFoundation                      0x0000000102d665f2 __CFRunLoopDoSources0 + 242
    15  CoreFoundation                      0x0000000102d8246f __CFRunLoopRun + 767
    16  CoreFoundation                      0x0000000102d81d83 CFRunLoopRunSpecific + 467
    17  GraphicsServices                    0x0000000103ca2f04 GSEventRunModal + 161
    18  UIKit                               0x00000001018b2e33 UIApplicationMain + 1010
    19  MyApp                               0x0000000100001c53 main + 115
    20  libdyld.dylib                       0x000000010335c5fd start + 1
    21  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

According to this question, when selecting a Main-Storyboard one can just reuse the iPhone storyboard, so it should be possible in general. However, I do want to have different Main storyboards and just combine some of the additional ones, which don't have any differences. Of course, I could copy over my existing iPad storyboard and load the correct one depending on the userInterfaceIdiom, but then I would have to change both Storyboards every time s.th. needs to change and that seems really error-prone and like a lot of unnecessary work.

I also tried another idea, recommending to manually edit the .xib-XML to change targetRuntime="iOS.CocoaTouch.iPad" to targetRuntime="iOS.CocoaTouch" (I think the other changes are not needed as they are only related to the display in IB) but the .xib still isn't found.

Is there any way to make a Storyboard universal or somehow force the OS to load the same Storyboard for both devices?

P.S.: I know that Xcode 6 has universal Storyboards and they are supposed to work on iOS 7. However, some other things in my app don't work when compiling with Xcode 6, so I would prefer to use Xcode 5 for now.

1

1 Answers

0
votes

Right, as usual, the error was something different. Some time ago, I moved the Storyboard file to a library project. However, the iPad app continued to work, since the old Storyboard was still in contained in the DerivedData folder. After deleting the DerivedData folder, it now ALSO fails on the iPad, which made me find out, that I specified the wrong bundle.

So to conclude: Using the same Storyboard file for iPhone and iPad is no problem if you load it by name. The setting of "targetRuntime" does not matter (I have one Storyboard file with targetRuntime="iOS.CocoaTouch.iPad" and one with targetRuntime="iOS.CocoaTouch", both are loaded on both device types and I don't see a difference in IB).