I have an iPad app that I would like to make Universal, however this seems alarmingly difficult. I've changed things around so that I support both builds, but when building, I get lots of errors about using UIPopOvers. Here're my questions:
Why does UI_USER_INTERFACE_IDIOM() not compile or register on 3.1.3?
Can I conditionally have variables in a class definition based on UI_USER_INTERFACE_IDIOM()?
If not, should I make two different view controllers?
Thanks!
Why does UI_USER_INTERFACE_IDIOM() not
compile or register on 3.1.3?
The UI_USER_INTERFACE_IDIOM macro is only available starting with 3.2. Same restrictions for the userInterfaceIdiom property of UIDevice. This means that you can only get universal application starting with SDK 3.2.
Can I conditionally have variables in
a class definition based on
UI_USER_INTERFACE_IDIOM()?
No. The UI_USER_INTERFACE_IDIOM macro is only a runtime shortcut to get the current UI idiom of the device.
If not, should I make two different
view controllers?
If you have very different UI between the two devices, it is wiser to use two different view controllers, and to create the right one at runtime (in the application controller for example) by using the UI_USER_INTERFACE_IDIOM macro.
I had pretty good luck with just selecting the target then going to Project->Upgrade current target for iPad.
My app is pretty simple, consisting mostly of table views and webviews, but it's worth making a backup and trying...
And yes, you have to submit it as a 3.2 app that can target 3.1.*
There are also a lot of other stuff that you have to do:
Make sure that it can be viewed at any orientation (got rejected the first time for this).
Make sure that you have all the new images created. you have to have 3 or 4 icons, instead of just one like an iPhone app needed. (iPad icon, iPhone icon, small icon for spotlight, etc).
And of course iPad sized screenshots for the store.
A really nice way that I use to test if it's an iPad or iPhone is to check if the device can use a split view controller, since for the forseeable future no device with a screen as small as an iPhone will be able to use the split view controller. I just created a function to do this for me:
+(BOOL)isIpad{ return NSClassFromString(#"UISplitViewController") != nil; }
Then anywhere in my app that I want to display something different depending on device, I just do a check for it:
int width = 150;
if([NabAppDelegate isIpad]){
width = 350;
} else {
width = 150;
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5,10,width,25)];
This is a lot better than checking against OS version like I've seen some suggest.
Related
I want to create a lite version of my app. When I searched on google, almost all the solutions mentioned to create a duplicate target and set necessary flags (to differentiate between full and lite version).
Now I did the necessary things but in my lite app I want some controls in one scene to be disabled. So how do I do it in the design mode?
With the flag sets I can differentiate between full and lite app while Runtime. But can I make the changes to a scene only for lite app in Design Time?
Or for every scene load, I'll have to check the flag and then do the disable/enable code in runtime.
What are my options? Please help.
I think the most manageable way is in your code. One example:
- (void)viewDidLoad {
[super viewDidLoad];
if (kIsLiteVersion) {
[someObject setEnabled:NO];
}
}
Or, perhaps you'd do this in init in some cases (maybe you want to not create certain objects in the lite version). Or, maybe use the condition to determine which storyboard view controller to push in some cases, and have some for the lite version.
i am totally new to iphone and i am trying to create a universal app.
Now I am creating an empty application. According to all tutorials , by checking universal option it should auto create appdelegates for both iphone and ipad.
But all i can see is only one appdelegate . Kindly tell me how can i create both.
Best Regards
Brayden is correct in answering that you almost never need multiple app delegates. All the delegate usually does is handle the moments when the application launches, suspends or terminates. Back in the days when iPhones ran iOS 4.0, and iPads ran iOS 3.2, you might need very different code in the delegate because only iOS 4.0 supported multitasking. Those days are long gone, and your delegate should probably act the same on all devices.
Yes, you sometimes do reach a point where your program must behave differently on iPhone and iPad. Check the idiom at that time and no earlier. Otherwise you're just duplicating code to no purpose.
My most recent app contains almost no special checks for iPhone or iPad. It doesn't even use different XIBs. Instead, my custom views implement layoutSubviews to fill the space available.
That said, once you understand app delegates, maybe you will find a situation where you need them to be different. If you are absolutely certain that your iPhone and iPad behavior will be so wildly divergent, you will need to:
Manually create a new class (preferably inheriting from the existing AppDelegate class)
In your main.m, send the class name of your new delegate to UIApplicationMain depending on the idiom.
See this answer to "Can I create App Delegate file in my project?" to see the changes to main.m.
You really should only be using one AppDelegate for a Universal application. You can use this to share common things that you'll do in there. What exactly do you need multiple AppDelegates for? If you need to do something specific to a device type (i.e. - iPhone or iPad) then you can do a ternary expression like below:
(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? NSLog(#"iPad") : NSLog(#"iPhone");
I have submitted my iPad app to apple and got approved. Now, i want to add iPhone support to the App.
My question no.1 is:
Q1. is it possible to make the app universal at this moment after submission?
If yes, i have question no.2
Q2. my iPhone app is exactly the same as the the iPad but only a few views are in different look due to the customization in screen size. What should I do in XCode to specify which class that iPhone/iPad is using respectively? I can build them smoothly when i separated them into 2 projects.
Thank you.
You can modify the same application and add support of other device. you need to resubmit application again.
From with in your code you can detect on which type of device it is executing and based on that you can load appropriate XiB file for each view controller.
Yes.It's easy. you have to create Universal app
File--->newproject-->Windowsbasedapplication
and then you select Product type Universal You have a separate view for iphone as well as
ipad
You can identify device using this
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// iPad stuff
}
else {
// iPhone/iPod stuff
}
Most of the UI stuff can be redone just with autosizing parameters, but some don't.
Also for specific classes that do not exist in iPhone/iPod (like UISplitViewController) you can use NSClassFromString, which will return the object class or nil if cannot be loaded.
Q1: Yes, just convert your project to universal and submit it with the same id.
Q2: Fairly easy, conver your project into universal by following the steps here (http://useyourloaf.com/blog/2010/4/7/converting-to-a-universal-app-part-i.html) . The basic idea is to extract your business logic from controllers and use different controller for iPhone and iPad. Don't try to implement it with code block like that
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// ipad goes here
}
else
{
// other
}
note:
If you google it, you will find this link, don't use it, it is outdated -- http://iphonedevelopment.blogspot.com/2010/04/converting-iphone-apps-to-universal.html
I've heard it's possible to output content from an iPad app to an external display, but the app has to be prepared for this and there are serious limitations. Any pointers?
And also, can this be done for iPhone? Is it the same?
As little indicates, you'll need to create a new UIWindow and attach it to the UIScreen for the external display. This UIWindow will host the content to be presented on the external display, so you'll need to build a distinct view hierarchy for that, separate from your main application interface. You also will need to listen for the UIScreenDidConnectNotification and UIScreenDidDisconnectNotification notifications that inform your application when the external display has been attached and removed.
I demonstrate how to do this in the video for the iPad session of my class on iTunes U, for which the course notes can be viewed here.
Matt Gemmell also did a very nice writeup on this recently, which you can read here.
The key to implementing this feature is contained in the UISCreen class:
http://developer.apple.com/iphone/library/documentation/uikit/reference/UIScreen_Class/Reference/UIScreen.html#//apple_ref/occ/clm/UIScreen/screens
Basically, your app will use UIScreen to get access to the external display screen and then set it as the screen for a new UIWindow (your app will have two UIWindows). The app can then add a ViewController to the new UIWindow that represents the second screen and off you go.
UIWindow *externalWindow.screen = [[[UIScreen screens] lastObject] retain];
[externalWindow addSubview:externalViewController.view];
It's pretty simple, but will take a little experimenting to get it working. It's a pain in the butt to debug your app on the device, since the 30-pin connector will be required to connect to the display, so cannot also be used for debugging. Perhaps there is a pass thru cable for allowing debug + external display, but I haven't had a chance to look.
Limitations:
You should be able to output video-quality bit rates, as apple has been able to achieve this with a few of their applications. That said, the external display will be limited to the screen resolution supported by the device, so things might not look crisp on your 108" LCD :-)
Platforms:
This should work on all iPads and on iPhones running 4.0+. You'll need the special cable which I believe is unique for iPhone and iPad ($30-40).
Can any one suggest how I can build Universal app for iPad as well iPhone. What all things I should take care of ? How to take care of resource images used ? Is it possible to have same code base should work for iPad as well iPhone.
In the Target->Project->getInfo->Build->target family-> select iPhone/iPad
And make the conditions everywhere whereever you set frame and also the resolution of the image required by iPAD is high.. so as per condition check whether its running on iPad or iPhone and based on that set your frame and image.
hAPPY cODING...
After creating your universal app (see #Suriya's post above) you should figure out in the app delegate whether you have an iPad or iPhone. Here is a simple tutorial to do just that.
Yes, you will need separate nibs and images for an iPad app. But, no, not all the code has to change. You can simply use class inheritance.
Example:
You have a MyTableViewController.h and .m file that work on the iPhone. This table has a custom cell, MyTableViewCell. Now you want your iPad app to get the same information, but display a larger table and a larger table cell. You then subclass your iPhone classes like so: MyiPadTableViewController : MyTableViewController and MyiPadTableViewCell : MyTableViewCell . This way you have access to all of your created functions in the parent class, but you can override how the information is displayed.
If you have a function - (void)doSomething:(id)foo; in your MyTableViewController class, you can use it in your MyiPadTableViewController class without writing any extra code, or override it if necessary. The point is you don't have to change code in two places, so it makes life a lot easier.