I'm trying to make a universal app, so i was wondering if i can connect two nib files ( 1 for iPad and the other for iphone ) to the same .h and .m files ?
i have 3 files TestView.h TestView.m and TestView.xib.... how can i connect a TestView_iPad.xib to the same TestView.h and TestView.m ?
i'm new to Xcode and i'm using Xcode 4 right now
thanx in advance :)
Short answer: Yes.
Provided you follow the model/view/controller style, you can re-use the same View and Viewcontroller (.h and .m) files in both an iPad nib and an iPhone nib (or storyboard). There will be occasions when you need to use the following type of code, though:
BOOL iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
if (iPad) {
.... iPad specific code like SplitViewController
} else {
.... iPhone / iPod Touch specific code
}
You may also need to check if the view controller you are in is on-screen (as on the iPad more than one ViewController can be onscreen), in which case use:
if (self.view.window) {
.... ViewController onscreen so do something otherwise do nothing
}
Also don't hardcode the bounds of the device's screen. Use the following to find your screen size (in points):
CGRect screenBounds = [[UIScreen mainScreen] bounds];
Hope this helps.
Related
I currently have an iOS iPhone application.
What i want to do , is make it universal so that i can target the iPad too.
What i did , was go to the target and change the iOS application target , from iPhone to universal.
Now when i run the application on my iPad , it automatically resizes all the views for the iPad.
However there are some views , with background pictures that dont look so good , cause i need to use higher resolution pictures or in general i should change some things in the iPad version.
Where are the iPad .nib files??? I mean , i only see the iPhone ones. When i run it on my iphone , these files are used. When i run it on my iPad everything is resized correctly , but where the hell are these .nib files?
The tutorials (pretty old) that i read , suggested that when you target the iPad too , new .nib files should be created exact copies for the ipad. Why i dont see these files?
You can have iOS automatically load the right xib based on the extension, akin to how Retina graphics work. If your xib is named Awesome, and you want to convert it into having an iPhone and an iPad version (instead of being shared, rename it such that:
iPhone version:
Awesome~iphone
iPad version:
Awesome~ipad
Then, when you tell iOS to load Awesome, it'll pick which one to load based on the current platform automagically. No need for if statements in your code! You can still if you want, but it's not required.
Note: You might need to perform a clean after the rename! Sometimes some files stick around in the build when renamed.
You will just need to make new .xib files and set them to the same class and you can init that viewController with a condition:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
yourVC = [[YourViewController alloc] initWithNibName:"YourViewController_ipad" andBundle:nil];
}
else
{
yourVC = [[YourViewController alloc] initWithNibName:"YourViewController" andBundle:nil];
}
Whenever possible you should try to use the same .xib but in a lot of cases it isn't possible to do that and look good so you just make a second. Xcode won't do it automatically for you.
Let's say that you have a class. We'll call it Two.
Here are the current files that make up the Two class.
Two.h
Two.m
Two.xib
Two.xib contains a UIView sized for the iPhone. In order to make a view sized for the iPad, you should create a new XIB file (name it Two_iPad.xib), connect the XIB to Two, resize the UIView in Two_iPad.xib for the iPad, and design accordingly.
When you are creating a new instance of Two, do the following.
Two *two;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
//they are using an iPad
two = [[Two alloc] initWithNibName:#"Two_iPad" bundle:nil];
} else {
//they are using an iPhone/iPod Touch
two = [[Two alloc] initWithNibName:#"Two" bundle:nil];
}
You are creating a new instance of Two; however, you are checking which device the user has, and using the corresponding XIB file.
I had an old project which uses XIB for each UIViewControler.That was intended for I Phone but now I want to make that project with universal build that is for Iphone as wall as IPad also.The problem is that when I changed the build type to Universal and used coding like
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
// ipad coordinates
}
else
{
//iphone coordinates
}
this the display is correct on iphone and ipad but on ipad the buttons are not taking click event on entire button but only on a small portion of button.Though I am not loading Nib but it is taking crated iphone xib file internally and I think thats why it's button behavior is not in accordance to ipad view. I am confused that what I should do?How to make copy of XIB for Ipad and load them depending upon device.It is to mention here that I am not loading any nib from my code but It is being called internally. Please help
For universal app you can make 2 xib
1 - > yourView_iPhone
2 - > yourView_iPad
And load each xib according yo your idiom
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
yourView *obj = [[yourView alloc]initWithNibName:#"yourView_iPad " bundle:nil];
// ipad coordinates
}
else
{
yourView *obj = [[yourView alloc]initWithNibName:#"yourView_iPhone " bundle:nil];
//iphone coordinates
}
I am createing my project on ios 6 but as per requirement the same project should be working in both ios 6 and older versions.
then how can I manage the .xib file for both versions because in ios 6 we have large .xib file.
Should I create new .xib file for older versions?
share your ideas friends,
thanx in advance.
No. You don't need to make separate nib files for iOS 6 and other lower OS versions. The only thing you need to follow is to disable "Use Auto Layout" feature of every nib in xcode 5 and can use autoresize property of views for making the view compatible for iOS 6 and other lower versions.
Create Two Xib Files one for iphone5 and other work for iPhone 3GS/4//4s one class
then
check for the device Idiom and height and it will work as following...
#define isiPhone5 ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568)
if(isiPhone5 == 1)
{
nibName = #"DesclaimerViewiPhone5";
}
else
{
nibName = #"DesclaimerView";
}
DesclaimerView* Obj = [[DesclaimerView alloc]initWithNibName:nibName bundle:nil];
[self.navigationControl pushViewController:obj animated:YES];
I believe that I did everything necessary to change my app for ipad (was for iphone at start). I can toggle the build status to either iphone (only), ipad (only) or iphone/ipad - and the app launches either in ipad or iphone simulator. I can do that forth and back at will.
I added the idiom to check for ipad and basically for one of my xib, instead of using the string of my xib to create the controller, I use the one for the ipad. So it is a new xib for ipad with all same graphical objects ( enlarged ;-) ) . I added the callbacks to function correctly with IB.
I can see everything fine and arrive on my new ipad view BUT when I click on one of my buttons... nothing happened like if my callbacks don't work. It is very surprising and actually I have no idea where to look as I compared most of the parameters between my iphone and ipad view and they are identical as far as I can see.
It must be something damn obvious so if one of you had the same issue and it was a very simple answer ... I guess that would be what I missed!
Thanks for your help in advance
Cheers,
geebee
EDIT1: Some code as requested
at start I have that to decide either way:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
examTFVC_NIB=#"ExamTFViewController-iPad";
}
else
{
examTFVC_NIB=#"ExamTFViewController";
}
Then to go to the right view:
ExamTFViewController *examTFViewController = [[ExamTFViewController alloc]
initWithNibName:globals.examTFVC_NIB bundle:nil];
But I have no problem loading the correct XIB. The issue is really the callback functions not being called...
Thanks for the help.
EDIT2:
I also realised that calling the extension of the xib xxx~ipad allows to avoid the example code above. And it works - but still no function can be called.
EDIT3:
IMPORTANT FINDING: if I move my buttons higher and on the left of the screen: they work! So it seems that the functions are called if the event are in the region of an iphone screen although I am on an ipad screen. I guess know it would be more obvious to find the issue! thanks for any help – geebee just now
ANSWER
iPad touch detected only in 320x480 region
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// to correct region size
CGRect rect = [[UIScreen mainScreen] bounds];
[window setFrame:rect];
// now, display your app
[window addSubview:rootController.view];
[window makeKeyAndVisible];
}
** OR OTHER SOLUTION **
Check the full screen at launch checkbox - only present in the ipad xib MainWindow
finally solved - with 2 methods - programmatically or via IB - in the edited section of the post.
I am trying to make an app which works on both iPhone and iPad. I am looking how to make an interface compatible on both. When the app loads I am displaying a table view. How can I load different nibs based on device? I am using this to switch between nibs.
if ([[UIDevice currentDevice] respondsToSelector:#selector(userInterfaceIdiom)])
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
device = #"iPad";
}
else
{
device = #"iPhone";
}
}
But in MainWindow.xib it says view is loaded from the view controller for iPhone. Can I make this dynamic based on device? ie I want to show from the start of app different nibs based on device.
Thanks.
Actually, Apple does all this automatically, just name your NIB files:
MyViewController~iphone.xib // iPhone
MyViewController~ipad.xib // iPad
and load your view controller with the smallest amount of code:
[[MyViewController alloc] initWithNibName:nil bundle:nil]; // Apple will take care of everything
You can do that in a similar way:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
mainMenu = [[MainMenu alloc] initWithNibName:#"MainMenuiPad" bundle:nil];
}else{
mainMenu = [[MainMenu alloc] initWithNibName:#"MainMenu" bundle:nil];
}
For making universal app,
1-set target family in info build tab for app as iPhone/iPad.
2- Delete window from main window.
3- Add two xib one for iPhone and one for iPad(by selecting iPad xib).
4- make appDelegate class as controller file for these xib's.
5- Add window on these xibs and view controller or navigation controller and by IB Inspector set load nib name and controller file here which one is your first view.
6- And then make differnet xib for iPad and iPhone which having tableview or other controls.
7-Make single contoller file or different controler file for different device for same you need to check the device by this if else condition
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
8-Now you need to load xib in appDelegate class in method didFinishL--
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
// load your nib for iPad here which having view controler or navigation controller as well window.
}else{
//load nib for iPhone.
}
Try this in your Info.plist:
Main nib file base name [NSMainNibFile]: MainWindow_iPhone
Main nib file base name (iPad) [NSMainNibFile~ipad]: MainWindow_iPad
I hope this helps you.