Help required in converting iPhone App to iPad - iphone

I am using the latest Xcode and i created a view based universal app and started building focusing on iPhone and now it is mandatory for me to put it in iPad. I didnt use the Interface builder in the development as more dynamic screen changes were expected from the beginning. In the code i have put all the screens with CGRECTMake(0,0,320,480).
Now when i tried to run the app in a iPad simulator, the app sticks to the top corners of the simulator with width as 320 and height as 480 and the rest of the screen looks white instead of coming up in the middle of the screen with a border and 2x options.
I have made the Main nib file base name (iPad) property in .plist file to my iPhone XIB name. I know this is one major reason why the app sticks to the top, but how to make this generic and make my app look proper in iPad?
Kindly help

If you create your views programatically you have to set everything that has a size twice, once for iPhone/iPod and once for iPad. You can do something like:
if ([Utils isIPad]) {
rect = CGRectMake(0,0,640,1024);
}
else {
rect = CGRectMake(0,0,320,480);
}
[Utils isIPad] would be something like:
+ (BOOL)isIPad {
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
Doing this with nibs is easier and faster, though. You just have to use the correct nib in that case. Something like:
if ([Utils isIPad]) {
login = [[LoginController alloc] initWithNibName:#"LoginController-iPad" bundle:nil];
}
else {
login = [[LoginController alloc] initWithNibName:#"LoginController" bundle:nil];
}

In response to dkk's answer, wouldn't it be more convenient to use the application frame of the main screen? This would return the correct frame size depending on the device without manual checks or hardcoded screen sizes.
[UIScreen mainScreen] applicationFrame]
More info: UIScreen Class Reference, refer to the applicationFrame property

Related

iphone ipad nib return same self.view.frame.size.width issue

I would like to get the current dimension of the screen.
i used self.view.frame.size.width
NSLog(#"%f",self.view.frame.size.width)
so when I run in the iphone simulator , it will return 320
however, when i run in the ipad simulator, it will still return me 320
I have different nib files for iphone and ipad
and they're getting the proper nib files and the target family is ipad/iphone
it should return 768 and so i can resize the images according to that.
any ideas?
try and use these
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenheight = [UIScreen mainScreen].bounds.size.height;
but UIScreen doesn't take into account the current interface orientation.
you will have to check for that also
or directly check for the device type
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
and
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
Change your targeted devices to Universal as in this picture
Is your iPad Nib file being used when running in a iPad Simulator? Maybe you want to check by changing something (maybe, change the location of,say, a button) in the iPad's NIB. This way, when the App runs, you can check if it's the iPhone's NIB or iPad's Nib.
First you check this:-
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
and
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
And also while allocating file:-
For iPhone:-
ABController *controller = [[ABController alloc] initWithNibName:#"ABController~iPhone" bundle:nil];
For iPad:-
ABController *controller = [[ABController alloc] initWithNibName:#"ABController~iPad" bundle:nil];
Make sure that
self.view.autoresizesSubviews=NO;
Imageview.autoresizingMask=NO;
is set to NO.
That will do your work

XCODE: Adjusting UIImageView Size from NIB for iPhone 5 Devices

I am trying to adjust the size of a background static UIImageView (from Nib file) for iPhone5 users. Unfortunately, the following code does not seem to make any difference on the background view's size.
Does anyone know why? Thanks in advance for any help you can provide.
ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
device = appDelegate.deviceType;
NSLog(#"The device platform is: %#", device);
if ([[device substringToIndex:8] caseInsensitiveCompare: #"iPhone 5"] == NSOrderedSame) {
[background sizeThatFits:CGSizeMake(320, 504)];
}
else {
[background sizeThatFits:CGSizeMake(320, 416)];
}
...
//Note: 'background' is declared in `ViewController.h` as, `IBOutlet` `UIImageView` *background, and is linked to the image view in ViewController_iPhone.xib
A few thoughts:
As demosten and shabzco suggested, I wouldn't use a device name/description to determine coordinates (if nothing else, what about the iPhone 6, etc.);
If you're going to set the frame programmatically, I would suggest setting the background.frame property based upon the view controller's view's bounds rather than hard coding the size of the image view. That way, the background is adjusted to the appropriate size of the view controller's view, not only regardless of device, but also regardless if that view controller is, at a later date, embedded as a child view controller of another container controller, etc. (E.g., what if you put your view in a navigation controller and tab bar controller, your own custom container controller, etc.). Also, don't make assumptions about the size of the status bar or other graphical elements. Let iOS figure all of this out for you with simply:
background.frame = self.view.bounds;
Or better yet, if you've added the background image view to the NIB itself, set the autosizing mask and don't change the frame programmatically at all. If you have autolayout turned off, just set the autosizing properties of your image view like so:
Bottom line, if you can, avoid explicit device name references in your code and avoid hard coded coordinates. To have hardcoded dimensions in your code will just make your app more fragile, susceptible to problems with new devices, new versions of iOS, embedding your view controller in additional container controllers, etc., and limits the reuse opportunities for your code.
Here's a better way to check between iPhone 5 and previous sized devices
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
[background sizeThatFits:CGSizeMake(320, 416)];
}
if(result.height == 568)
{
[background sizeThatFits:CGSizeMake(320, 504)];
}
}
sizeThatFits does not change size. You should modify background.frame. Something like:
background.frame = CGRectMake(background.frame.origin.x, background.frame.origin.y, 320, 416);
and
background.frame = CGRectMake(background.frame.origin.x, background.frame.origin.y, 320, 504);
Also make sure your UIImageView does not have flexible width or height in Size inspector tab while editing your Nib file.

How to make xib compatible with both iphone 5 and iphone 4 devices

I am trying to layout my xib so that layout fits in both iphone 5 (4 inches retina) and 3.5 devices.
Because I have to support IOS-5 I cannot use autolayout. I have to use springs and Struts.
I tried everything in interface-builder. But either my view is going beyond the bottom of iphone-3.5-inch or not filling completely the iphone-4-inch-retina.
Can someone give a hint how to actually make an xib compatible to both the devices?
For more clarity I am adding screenshots:
When I set size 3.5 in attribute inspector:
it looks in iphone-5. There is a space below the buttons:
If I set size 4 inch in interface builder. You can see that bottom buttons are not visible in iphone-4.
So you will ask what are the settings I am using. Here are they:
You add new category for UIviewController and add this code in .h file
- (id)initWithNibNameforIphone4:(NSString *)nibNameOrNil4 NibNameforIphone5:(NSString *)nibNameOrNil5 NibNameforIpad:(NSString *)nibNameOrNilpad bundle:(NSBundle *)nibBundleOrNil;
Add this code in your .m file
- (id)initWithNibNameforIphone4:(NSString *)nibNameOrNil4 NibNameforIphone5:(NSString *)nibNameOrNil5 NibNameforIpad:(NSString *)nibNameOrNilpad bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super init])
{
self = [self initWithNibName:[self CheckDeviceIphone4:nibNameOrNil4 Iphone5:nibNameOrNil5 Ipad:nibNameOrNilpad] bundle:nibBundleOrNil];
}
return self;
}
-(NSString *)CheckDeviceIphone4:(NSString *)iphone4 Iphone5:(NSString *)iphone5 Ipad:(NSString *)ipad {
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ? ipad :([[UIScreen mainScreen] bounds].size.height == 568) ? iphone5 :iphone4;
}
Open YouProject-Prefix.pch file and import your category here
now you just use this in all over project like this
self.firstView=[[firstView alloc]initWithNibNameforIphone4:#"firstView4" NibNameforIphone5:#"firstView" NibNameforIpad:#"firstViewIpad" bundle:[NSBundle mainBundle]];
thanks and any question then comment and dont forget to upvote :-)
\
Try adding this to all your controllers which need to support iPhone 5:
- (void) loadView
{
[super loadView];
self.view.frame = [UIScreen mainScreen].bounds;
}
Just set view size to None using Interface-builder
It will take view size at runtime, just you need to take care of origin and autosizing for each element(UILabel, UIImage, etc.) in the view.
Interface-builder(XIB) -> Attribute Inspector -> Simulated Metrics - Size: None
I was struggling with this today, and no matter what I did, my views were always showing up as 320x480, even when running on the retina 4" simulator. Even [UIScreen mainScreen].bounds was returning 320x480!
I found that adding the Default-568h#2x.png launch image was the key to getting iOS to recognize my app as 'retina 4" ready'. Once I did that, I found had to do nothing else to get nibs to automatically size without the black bars. No need to have two separate xibs, change settings in Interface Builder, overriding loadView, etc.
You need not use a different nib for the 3.5 inch and 4 inch devices. Design the app for the 4 inch device and set the AutoResizingMask correctly and it should work correctly.
In your case just set the AutoResizingMask to
[view setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];
The autoresizing mask places the view correctly to its position in both the devices.
If you go with the solution of using 2 xib files; in your initWithNibName() method simply make a call to super with the different nib name.
I would test on the original 480 height dimension rather than on the 568 height so that the larger xib file is selected when Apple releases a larger screen. In the future, at least the larger xib won't be letter-boxed as much as the smaller one.
// From MainView.m
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
// iPhone Classic
self = [super initWithNibName:#"MainView" bundle:nibBundleOrNil];
}
else
{
// iPhone 5 or maybe a larger iPhone ??
self = [super initWithNibName:#"MainView5" bundle:nibBundleOrNil];
}
return self;
}
I have an idea. Let separate your UI into header, body and footer (like website). Then in your code console, locate to Size Inspector and use the Autosizing.
Notice the outside lines of the square, it is your control location against main view. Set the controls (navigation bar, UIImageView, UIButton etc.) in header part and body part attached to Top and the controls (Bookmark, Close etc.) in footer to Bottom.
Everytime you run, the controls will attach to their autosizing settings. You will have a space between header/body and footer on iPhone 5 but I think it's fine.
Define below line and check condition based on device.
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 )
if (IS_IPHONE_5) {
btnBookmark.frame=CGRectMake(0, 460, 100, 70);
btnBookmark.frame=CGRectMake(150, 460, 100, 70);
}
else {
btnBookmark.frame=CGRectMake(0, 360, 100, 70);
btnBookmark.frame=CGRectMake(150, 360, 100, 70);
}
I was having an issue with 3.5" vs. 4" as well, and I misunderstood what was wrong so I wanted to document it here incase it helps anyone.
If you are trying to access self.view.frame it will not be correctly reported until viewDidAppear or some similar event. If you try to access self.view.frame from within viewDidLoad then you can be reported the dimensions of the frame before autosizing takes place.
In your storyboard, click 'Show file inspector'.
Under Interface builder document->Document versioning, select Deployment=iOS 5 (or your choice).
If this doesn't work, you need to work with each of your views.
Select them. Under Attributes inspector for each of them, under View section, see Mode attribute. Set this to 'Redraw'.
If even that doesn't give satisfactory result, set the view size to the smallest of all the version you are going to use. And set the Mode attribute = 'Scale to fill'.
Programmatically, Mode attribute is view.contentmode property.
Without using autolayout you may need to handle a lot of things in code. I assume most of your layout can work well with springs and struts but some UI elements can't so just manually set the frames of certain objects according to the size of your view is necessary.
ivanzoid's snippet above that queries for the whole screen size does the trick so long as you remember to subtract the offsets for navigation and toolbars (totalling 64 under most conditions).
It's the view height that needs to be adjusted; springs and struts otherwise take care of it.
Retesting my app on the iPhone 5 I only had to do this on one screen with some runtime control position adjustments. Every other case is handled by XIB defaults.
If you dont want use two xib and interested to do using Autosizing here
If your UI is too complicated and contains too many UIControls , then I suggest to do the following in viewDidLoad():
NSLog(#"Iphone %f ",[[UIScreen mainScreen] bounds].size.height);
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
//design frames of your controls accordingly add add the controls as subview to
self.view
//this is iphone 5 xib
} else
{
//design frames of your controls accordingly add add the controls as subview to
self.view
// this is iphone 4 xib
}

iPhone 5 size support [duplicate]

The new iPhone 5 display has a new aspect ratio and a new resolution (640 x 1136 pixels).
What is required to develop new or transition already existing applications to the new screen size?
What should we keep in mind to make applications "universal" for both the older displays and the new widescreen aspect ratio?
Download and install latest version of Xcode.
Set a Launch Screen File for your app (in the general tab of your target settings). This is how you get to use the full size of any screen, including iPad split view sizes in iOS 9.
Test your app, and hopefully do nothing else, since everything should work magically if you had set auto resizing masks properly, or used Auto Layout.
If you didn't, adjust your view layouts, preferably with Auto Layout.
If there is something you have to do for the larger screens specifically, then it looks like you have to check height of [[UIScreen mainScreen] bounds] as there seems to be no specific API for that. As of iOS 8 there are also size classes that abstract screen sizes into regular or compact vertically and horizontally and are recommended way to adapt your UI.
If you have an app built for iPhone 4S or earlier, it'll run letterboxed on iPhone 5.
To adapt your app to the new taller screen, the first thing you do is to change the launch image to: Default-568h#2x.png. Its size should be 1136x640 (HxW). Yep, having the default image in the new screen size is the key to let your app take the whole of new iPhone 5's screen.
(Note that the naming convention works only for the default image. Naming another image "Image-568h#2x.png" will not cause it to be loaded in place of "Image#2x.png". If you need to load different images for different screen sizes, you'll have to do it programmatically.)
If you're very very lucky, that might be it... but in all likelihood, you'll have to take a few more steps.
Make sure, your Xibs/Views use auto-layout to resize themselves.
Use springs and struts to resize views.
If this is not good enough for your app, design your xib/storyboard
for one specific screen size and reposition programmatically for the
other.
In the extreme case (when none of the above suffices), design the two Xibs and load the appropriate one in the view controller.
To detect screen size:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
{
// iPhone Classic
    }
    if(result.height == 568)
{
// iPhone 5
    }
}
The only really required thing to do is to add a launch image named "Default-568h#2x.png" to the app resources, and in general case (if you're lucky enough) the app will work correctly.
In case the app does not handle touch events, then make sure that the key window has the proper size. The workaround is to set the proper frame:
[window setFrame:[[UIScreen mainScreen] bounds]]
There are other issues not related to screen size when migrating to iOS 6. Read iOS 6.0 Release Notes for details.
Sometimes (for pre-storyboard apps), if the layout is going to be sufficiently different, it's worth specifying a different xib according to device (see this question - you'll need to modify the code to deal with iPhone 5) in the viewController init, as no amount of twiddling with autoresizing masks will work if you need different graphics.
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
NSString *myNibName;
if ([MyDeviceInfoUtility isiPhone5]) myNibName = #"MyNibIP5";
else myNibName = #"MyNib";
if ((self = [super initWithNibName:myNibName bundle:nibBundleOrNil])) {
...
This is useful for apps which are targeting older iOS versions.
Here you can find a nice tutorial (for MonoTouch, but you can use the information for Non-MonoTouch-projects, too):
http://redth.info/get-your-monotouch-apps-ready-for-iphone-5-ios-6-today/
Create a new image for your splash/default screen (640 x 1136 pixel) with the name "Default-568h#2x.png"
In the iOS Simulator, go to the Hardware -> Device menu, and select "iPhone (Retina 4-inch)"
Create other images, e.g. background images
Detect iPhone 5 to load your new images:
public static bool IsTall
{
get {
return UIDevice.currentDevice.userInterfaceIdiom
== UIUserInterfaceIdiomPhone
&& UIScreen.mainScreen.bounds.size.height
* UIScreen.mainScreen.scale >= 1136;
}
}
private static string tallMagic = "-568h#2x";
public static UIImage FromBundle16x9(string path)
{
//adopt the -568h#2x naming convention
if(IsTall())
{
var imagePath = Path.GetDirectoryName(path.ToString());
var imageFile = Path.GetFileNameWithoutExtension(path.ToString());
var imageExt = Path.GetExtension(path.ToString());
imageFile = imageFile + tallMagic + imageExt;
return UIImage.FromFile(Path.Combine(imagePath,imageFile));
}
else
{
return UIImage.FromBundle(path.ToString());
}
}
It's easy for migrating iPhone5 and iPhone4 through XIBs.........
UIViewController *viewController3;
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
UIViewController *viewController3 = [[[mainscreenview alloc] initWithNibName:#"iphone5screen" bundle:nil] autorelease];
}
else
{
UIViewController *viewController3 = [[[mainscreenview alloc] initWithNibName:#"iphone4screen" bundle:nil] autorelease];
}
I solve this problem here. Just add ~568h#2x suffix to images and ~568h to xib's. No needs more runtime checks or code changes.
I had added the new default launch image and (in checking out several other SE answers...) made sure my storyboards all auto-sized themselves and subviews but the retina 4 inches still letterboxed.
Then I noticed that my info plist had a line item for "Launch image" set to "Default.png", which I thusly removed and magically letterboxing no longer appeared. Hopefully, that saves someone else the same craziness I endured.
I guess, it is not going to work in all cases, but in my particular project it avoided me from duplication of NIB-files:
Somewhere in common.h you can make these defines based off of screen height:
#define HEIGHT_IPHONE_5 568
#define IS_IPHONE ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 ([[UIScreen mainScreen] bounds ].size.height == HEIGHT_IPHONE_5)
In your base controller:
- (void)viewDidLoad
{
[super viewDidLoad];
if (IS_IPHONE_5) {
CGRect r = self.view.frame;
r.size.height = HEIGHT_IPHONE_5 - 20;
self.view.frame = r;
}
// now the view is stretched properly and not pushed to the bottom
// it is pushed to the top instead...
// other code goes here...
}
In a constants.h file you can add these define statements:
#define IS_IPAD UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
#define IS_IPHONE UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone
#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE_5 (!IS_IPAD && IS_WIDESCREEN)
To determine if your app can support iPhone 5 Retina use this:
(This could be more robust to return the type of display, 4S Retina, etc., but as it is written below, it just returns if the iPhone supports iOS5 Retina as a YES or NO)
In a common ".h" file add:
BOOL IS_IPHONE5_RETINA(void);
In a common ".m" file add:
BOOL IS_IPHONE5_RETINA(void) {
BOOL isiPhone5Retina = NO;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if ([UIScreen mainScreen].scale == 2.0f) {
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
if(result.height == 960){
//NSLog(#"iPhone 4, 4s Retina Resolution");
}
if(result.height == 1136){
//NSLog(#"iPhone 5 Resolution");
isiPhone5Retina = YES;
}
} else {
//NSLog(#"iPhone Standard Resolution");
}
}
return isiPhone5Retina;
}
First of all create two xibs and attach all delegates,main class to the xib and then u can put in this condition mentioned below in your appdelegate.m file in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
self.ViewController = [[ViewController alloc] initWithNibName:#"ViewControlleriphone5" bundle:nil];
}
else
{
self.ViewController = [[ViewController alloc] initWithNibName:#"ViewControlleriphone4" bundle:nil];
}
you can use it any where in the program depending upon your requirements even in your ViewController classes. What matters the most is that you have created two xib files separate for iphone 4(320*480) and iphone 5(320*568)
Try the below method in a singleton class:
-(NSString *)typeOfDevice
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
return #"Iphone";
}
if(result.height == 568)
{
return #"Iphone 5";
}
}
else{
return #"Ipad";;
}
return #"Iphone";
}
You can use the Auto Layout feature and create the design using iPhone 5 screen resolution and it will work for the both 4" and 3.5" devices, but in this case you should have a enough knowledge of layout manager.
Checking bounds with 568 will fail in landscape mode. iPhone 5 launches only in portrait mode but if you want to support rotations then the iPhone 5 "check" will need to handle this scenario as well.
Here's a macro which handles orientation state:
#define IS_IPHONE_5 (CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size, CGSizeMake(640, 1136)))
The use of the 'preferredMode' call is from another posting I read a few hours ago so I did not come up with this idea.
First show this image. In that image you show warning for Retina 4 support so click on this warning and click on add so your Retina 4 splash screen automatically add in your project.
and after you use this code :
if([[UIScreen mainScreen] bounds].size.height == 568)
{
// For iphone 5
}
else
{
// For iphone 4 or less
}
I never faced such an issue with any device as I've had one codebase for all, without any hardcoded values. What I do is to have the maximum sized image as resource instead of one for each device. For example, I would have one for retina display and show it as aspect fit so it will be views as is on every device.
Coming to deciding the frame of button, for instance, at run time. For this I use the % value of the patent view, example , if I want the width to be half of parent view take 50 % of parent and same applies for height and center.
With this I don't even need the xibs.
You can use this define to calculate if you are using the iPhone 5 based on screen size:
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
then use a simple if statement :
if (IS_IPHONE_5) {
// What ever changes
}
Peter, you should really take a look at Canappi, it does all that for you, all you have to do is specify the layout as such:
button mySubmitButton 'Sumbit' (100,100,100,30 + 0,88,0,0) { ... }
From there Canappi will generate the correct objective-c code that detects the device the app is running on and will use:
(100,100,100,30) for iPhone4
(100,**188**,100,30) for iPhone 5
Canappi works like Interface Builder and Story Board combined, except that it is in a textual form. If you already have XIB files, you can convert them so you don't have to recreate the entire UI from scratch.
You can manually check the screen size to determine which device you're on:
#define DEVICE_IS_IPHONE5 ([[UIScreen mainScreen] bounds].size.height == 568)
float height = DEVICE_IS_IPHONE5?568:480;
if (height == 568) {
// 4"
} else {
// 3"
}
You could add this code:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
if ([[UIScreen mainScreen] respondsToSelector: #selector(scale)]) {
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
if(result.height == 960) {
NSLog(#"iPhone 4 Resolution");
}
if(result.height == 1136) {
NSLog(#"iPhone 5 Resolution");
}
}
else{
NSLog(#"Standard Resolution");
}
}
This is a real universal code, you can create 3 different story board:
Set your project Universal mode, and set your main story iPhone with the iPhone5 storyboard and the ipad main with iPad target storyboard, now add new storyboard target for iphone and modify the resolution for iphone 4s or less now implement your AppDelegate.m
iPhone4/4s (is the same for 3/3Gs) one for iPhone5 and make the project universal, with a new Storyboard target for iPad, now in to AppDelegate.m under the didFinishLaunching add this code:
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
UIStoryboard *storyBoard;
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width *scale, result.height *scale);
//----------------HERE WE SETUP FOR IPHONE4/4s/iPod----------------------
if(result.height == 960){
storyBoard = [UIStoryboard storyboardWithName:#"iPhone4_Storyboard" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
//----------------HERE WE SETUP FOR IPHONE3/3s/iPod----------------------
if(result.height == 480){
storyBoard = [UIStoryboard storyboardWithName:#"iPhone4_Storyboard" bundle:nil];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
[self.window setRootViewController:initViewController];
}
}
return YES;
}
So you have created a Universal app for iPhone 3/3Gs/4/4s/5 All gen of iPod, and All type of iPad
Remember to integrate all IMG with myImage.png and myImage#2x.png
According to me the best way of dealing with such problems and avoiding couple of condition required for checking the the height of device, is using the relative frame for views or any UI element which you are adding to you view for example: if you are adding some UI element which you want should at the bottom of view or just above tab bar then you should take the y origin with respect to your view's height or with respect to tab bar (if present) and we have auto resizing property as well. I hope this will work for you
Rather than using a set of conditionals you can resize your view automatically using the screen size.
int h = [[UIScreen mainScreen] bounds].size.height;
int w = [[UIScreen mainScreen] bounds].size.width;
self.imageView.frame = CGRectMake(20, 80, (h-200), (w-100));
In my case I want a view that fills the space between some input fields at the top and some buttons at the bottom, so fixed top left corner and variable bottom right based on screen size. My app fills the image view with the photo taken by the camera so I want all the space I can get.
If you need to convert an already existing app to universal, you need to select corresponding xib file->show Utilities-> Show Size inspector.
In Size inspector you can see Autosizing, by using this tool you can convert to existing iOS App.
Using xCode 5, select "Migrate to Asset Catalog" on Project>General.
Then use "Show in finder" to find your launch image, you can dummy-edit it to be 640x1136, then drag it into the asset catalog as shown in the image below.
Make sure that both iOS7 and iOS6 R4 section has an image that is 640x1136. Next time you launch the app, the black bars will disappear, and your app will use 4 inch screen
Point worth notice - in new Xcode you have to add this image file Default-568h#2x.png to assets
Use the Auto Layout feature for views. It will adjust automatically to all resolutions.
Create two xibs for a controller having controller name with suffix either ~iphone or ~ipad. At compile time, Xcode will take the right xib based on the device.
Use size classes, if you want to create a single xib for both iPhone and iPad, if the view is simple enough to port to iPhone and iPad.
There is a slight problem when testing on both iOS device and iOS Simulator. It appears that simulator (XCode 6.0.1) gives switched values for width and height in [[UIScreen mainScreen] bounds].size depending on a device orientation.
So this might be a problem when determinating the right physical screen size. This code helps also to distinct all 2014. iPhone model generations:
iPhone4s
iPhone5 (and iPhone5s)
iPhone6 (and iPhone6+)
It can also be easily changed to make the distinction between e.g. iPhone6 from iPhone6+.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
if (iOSDeviceScreenSize.width > 568 || // for iOS devices
iOSDeviceScreenSize.height > 568) // for iOS simulator
{ // iPhone 6 and iPhone 6+
// Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone6
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone6" bundle:nil];
NSLog(#"loaded iPhone6 Storyboard");
}
else if (iOSDeviceScreenSize.width == 568 || // for iOS devices
iOSDeviceScreenSize.height == 568) // for iOS simulator
{ // iPhone 5 and iPod Touch 5th generation: 4 inch screen (diagonally measured)
// Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone5
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone5" bundle:nil];
NSLog(#"loaded iPhone5 Storyboard");
}
else
{ // iPhone 3GS, 4, and 4S and iPod Touch 3rd and 4th generation: 3.5 inch screen (diagonally measured)
// Instantiate a new storyboard object using the storyboard file named Storyboard_iPhone4
storyboard = [UIStoryboard story boardWithName:#"MainStoryboard_iPhone" bundle:nil];
NSLog(#"loaded iPhone4 Storyboard");
}
}
else if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{ // The iOS device = iPad
storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPadnew" bundle:nil];
NSLog(#"loaded iPad Storyboard");
}
// rest my code
}
I would suggest to use Autoresizing Mask in your applications according to your UI interface, it saves a lot of trouble and is better than making different UI for iPhone 4 and 5 screens.

Position UILabel when app is opened in iPad

I have a universal iPhone/iPad app. On the main menu I have a UIImage and UILabel that show the current weather conditions outside; the UILabel shows the current temperature.
I am using the same XIB for both versions, I made all of the graphics I am using a high resolution so they scale good for the iPad.
On the iPhone version, right under the UIImage the label is centered, which is what I want it to do. When it loads in the iPad, the UIImage gets a big bigger, but the label stays in the same position, to the left of the screen, not centered under the bigger image. I have tried many different things in IB to get it to center, and I cannot get it to.
Would it also be possible to make the text size bigger when loaded on the iPad?
Here are some images to portray what I am talking about:
iPhone version:
http://img855.imageshack.us/i/iphonei.png/
iPad version:
http://img163.imageshack.us/i/ipadh.png/
Not sure about your label issue, but to vary text size for iPad create a function to test if you're on an iPad and then use that to vary your code as required. Here's a function to to do the job.
BOOL isIPad()
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
return YES;
}
return NO;
}
And then just write some conditional code. For example:
UIButton *infoCircle;
if (isIPad())
{
infoCircle = [UIButton buttonWithType:UIButtonTypeInfoDark];
}
else
{
infoCircle = [UIButton buttonWithType:UIButtonTypeInfoLight];
}
In your case, you'll want to adjust the label font size with something like:
if (isIPad())
{
[[self mainLabel] setFont: [UIFont systemFontOfSize: 18.0]];
}
else
{
[[self mainLabel] setFont: [UIFont systemFontOfSize: 14.0]];
}
If Interface Builder is giving you grief, you can also use the same approach to reposition the UILabel programmatically. Sometimes this is quicker, especially once your interface has settled down.