Updating iPhone app to Universal: IBOutlets - iphone

First off, I will say i've spent 6 hours on this topic and have read everything the internet has to provide, which is why i came here.
I have converted to Universal, Xcode created the MainWindow-iPad.xib and everything seems fine.
Here are my questions:
1) What are the naming conventions for new iPad-specific xibs? Xcode created "-iPad" but i believe im supposed to be making them "~ipad". Why the difference?
2) (MOST IMPORTANT) After creating several "~ipad" xibs, Xcode seems to know to load these. So I'll copy the content in say, "RootViewController.xib"
and paste it in "RootViewController~ipad.xib". THIS IS THE PROBLEM: this new ~ipad xib has no outlets or referencing outlets!
I can't link the buttons on my page to anything. How do i do this without having a separate ~ipad .m and .h for everything?
Thank you guys for your help! I'm going to write a tutorial on this once I get this all working.

Just set the class of that ~iPad nib to be the same classname as the cooresponding iPhone nib. This is done in the inspector in Interface Builder. You may have to connect the outlets back up depending on the order you do things. I would think that if you copy the objects from the iPhone nib to the iPad nib AFTER you set the class, then the outlets would stay wired up.

Related

How to generate .m/.h files from Storyboard?

Is there a convenient way to generate code from any new view controllers I've created on the storyboard? For example when you create a new iOS application, XCode will set up a skeleton class for your view controller.
Thanks!
I don't think so. You need to create a new ViewController subclass in XCode but uncheck the "Create Xib for this class" box (not sure if that is exactly what it says). Then select your newly made view controller in storyboard and change it to the class you just created.
Ok the skeleton you are talking about is just a template for your application. You are asking for a dynamic template generator from your storyboard and maybe Apple can figure out how to do this in a non distant future but in this moment I think you can't do that. After you created the storyboard file with your complex scheme you need to manually create all your viewController subclass you used in the storyboard. It's not a big deal ... I suppose your application doesn't have thousand ViewController so you can do it manually.
Apple are working hard to simplify developers job but Xcode can't do everything for you.
You can try to post this answer directly to Apple throughout the bugreport Apple website and post it as improvement to implement in future Xcode release.
Lets try it :)

iOS universal app xcode 4 starter tips

I'm trying to start a universal app using Xcode and I'm totally lost. I started the universal Window based app from the templates. I'm trying to have a UITableViewController for the iPhone, and a UISplitViewController for the iPad. I see 3 appDelegates, and did read this post http://www.kotancode.com/2011/04/05/ios-universal-apps/ , but I'm still really confused. I started by creating a UIViewController subclass in the iPadAppDelegate folder with a .xib. Nothing is in the file yet. Then in the iPadAppDelegate.h:
#property (nonatomic, retain) IBOutlet HomeViewController_iPad *homeViewController;
Dragged a UIViewController in the MainWindow_iPad.xib, changed the class to HomeViewController, and tried dragging an outlet from the MainWindow to the UIViewController and I am not able to connect the HomeViewController.
I thought I could do somthing like this for the iPhoneAppDelegate as well, but I believe I am missing something from the Universal App Template. Can someone give me some advice on how these 3 appDelegates work and how I can get started? TIA
Universal Apps are really simple once you grasp how they work.
The reason there are three AppDelegates is that you usually have one that is the base class for an iPhone and iPod specific app delegate. The entry-point into your iPhone or iPad Application is based on the configuration in your .plist file, if you select the project in xCode 4 it will show you a graphical configuration dialog that will allow you to change those properties. The so called "Main Interface" is independently selectable for iPhone and iPad in the respective deployment section. The Main Nib file does contain a serialized version of the device specific app delegate, which will then be "woken up" when the application is loading. This process is triggered from your Main() method when
UIApplicationMain(argc, argv, nil, nil)
is called. UIApplicationMain does take care of loading the proper NIB file, based on the device it is run on.
Thats all there is.

iPhone Obj C - change startup root class?

I am learning iPhone Obj C slowly. I have a XIB with several views and all works well. I need to have a 2nd XIB to control another set of views but haven't been able to make it work.
So I created the 2nd class and a 2nd XIB, all called one.h one.m one.xib and the same for the new one is all two.*
As it didnt work I was going try and change the app to start on the TWO class rather than the ONE class. In the plist I changed the Main Nib base file but that didnt seem to do anything.
Where do you specify what the start up class is? That way I can make sure I did everything correctly first, and then go back to the code that is supposed to call the two class and xib.
Also if anyone has any sample code to go from one class and xib to another, please let me know.
thanks!
In your AppDelegate class make sure the ViewController being allocated and set to the window is the one desired.
Your project's [ProjectName]-Info.plist file decides which Nib file is used when the application starts, in the key NSMainNibFile. (By default, this is set to MainWindow.)
A standard MainWindow.nib file will define the "root" class, which is usually [ProjectName]AppDelegate. You can, however, change this by editing the nib.
I had to set the CLASS IDENTITY to the proper class for the app delegate on the XIB for both XIB.
Then I changed the plist to point to the XIB I wanted to start as root.
Both of the answers above helped me find this.
THANK YOU

Proper setup for universal OpenGL ES iPhone/iPad app in XCode 4

I've been trying all morning to setup a univeral OpenGL-ES app with limited success. I can easily get the default OpenGL template app to compile for both devices and run just fine by adding a new XIB file and setting the proper values in it. Where I'm having trouble is figuring out how to give each device it's own unique GUI. Currently both devices use the same ViewController.xib file that is created with the project. How can I create a separate XIB file that uses the same ViewController .h and .m files? Do I need to create a separate AppDelegate class for each device type, or can they be shared?
The standard approach is to have a base AppDelegate class, and then subclass this for each device. Each delegate would then load its own XIB file with the correctly sized UIWindow and add the views.

What are the differences between Xcode generated .nib/.xib and interface builder .nib/.xib template?

I am new to iPhone development so I have been working through some tutorials. What I don't understand is how xib fit into the work flow.
In a tutorial, one of the instruction is to create a new UIViewController subclass with "XIB for User Interface" selected. On my first try, I neglected to check that option and I thought may be I can just create the xib in Interface Builder but that didn't work. ( I created the xib using Cocoa Touch View Template, with the same name as the UIViewController and saved it the into project directory so it was added to the project.) I even changed the Class Identify for the File's Owner and hooked up the view outlet (the two differences I noticed when I inspected the xib generated from Xcode.)
So what are the differences between Xcode generated .xib (from UIViewController Template) and the IB .xib template?
XIB files created as part of the New File flow in Xcode have their File's Owner class pre-set, as well as certain outlets (view) already connected. Otherwise, there's not much difference.
The XIB File is basicly an uncompile NIB File, XIBs can always be edited in Xcode (unless they are outdated or corrupt) but most NIBs are compressed (flat) and are unopenable. However the older NIBs are bundles containing some source/archived including designable.nib which is often just the renamed XIB File and a keyedobjects.nib which is an other compiled NIB
NIB = Nxt Interface Builder
XIB = Xml Interface Builder
Although the new archived NIB files are unopenable to most applications including Xcode, they can still potentially be unarchived. I found this freeware application called NibUnlocker On The CharlesSoft Website which can potentially disassemble a compressed Nib file and exports it as an XIB document. This application is still fairly buggy but it is sometimes very accurate based on the Nibs contents.
(NibUnlocker is a very inaccurate name, Nibs are not locked they are archived)
Click to Download Nib Unlocker
If You wish to know a bit more you can read some additional information I have provided below in regards to the NIB and XIB Formats:
Nxt Interface Builder Anatomy:
Archived NIBs
A Compressed NIB file is complicated file to analyse but this is not impossible. The structure of these files are based off of a compacted property list (begins with "bplist00") and some of its contents are archived through NSKeyedArchiver. Since a NIB is formatted as a property list, This allows a small hack: if you actually change the extension of a Nib to .plist, eg. ArchivedNib.nib to ArchivedNib.plist You will actually be able to open it in Xcode viewing it as a Property List. When you view a Nib as a property list you will probably get a few base properties such as $version, $objects, $archiver and $top.
Useful Notes
A CFKeyedArchiverUID object is actually a redirector, in the {value = xx}, the value is an offset for a item in the $objects array from the start of the array. eg. <CFKeyedArchiverUID 0x60800002bc20 [0x7fffef6b8c30]>{value = 29}, value = 29, the result would be the 29th item in the $object's array. In Objective C you can retrieve this value from an NSArray with this method :
+ (NSUInteger)valueForKeyedArchiverUID:(id)keyedArchiverUID {
void *uid = (__bridge void*)keyedArchiverUID;
NSUInteger *valuePtr = uid+16;
return *valuePtr;}
like if this helped ;-)
I'm not sure I'm following your question. When you created a xib file in Xcode, attempting to edit the xib file will bring up IB. So effectively you are using IB to edit the xib file in Xcode. I never tried creating a "stand-alone" xib file in IB and then hook it up to a project in xcode.
The only reason such an approach may not work is that when you create the xib file within the context of a project, there are associations created (such as "mainnib file base name" attribute in the plist) which will not be automatically generated when you attempt to use a standalone xib file with the xcode project.
It sounds like you configured the view xib properly, by setting the View outlet and configuring the custom class for File's Owner, but perhaps the problem was with the UIViewController subclass.
If your view controller subclass had implemented the -[UIViewController loadView] method directly, it'd prevent the NIB from loading. In the default implementation, the UIViewController will load the NIB file with the same name as the view controller. If you override this method to initialize the view a different way (e.g. completely programmatically), the default implementation that loads the NIB won't run.
Deleting an override of the -[UIViewController loadView] method in your subclass, or ensuring the names match, might resolve any discrepancies.
XIBs are XML. Diff them and find out for yourself.