Best way for creating universal native iPhone/iPad application? - iphone

Which approach is good to create universal native application for iPhone/iPad:
1) Create separate NIB files for iphone and iPad versions and load the specific version by checking (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad).
2) Get the dimension of the main screen and frame the view accordingly
CGRect mainWindow = [[UIScreen mainScreen] bounds];
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, mainWindow.size.width, mainWindow.size.height)];
Please suggest if any other approach that I missed
Thanks,
Ajay

I am using the first approach, in many cases, at least for my own it is sufficient to set autoresizing masks. You have not said anything about this, but if your application will look pretty much the same (up-scaled layout) this works fine. In the cases I need another layout I have checked whether it is an iPad/iPhone and loaded the correct NIB, or used the GUI code in loadView based on the device.
From you example code with the webview you could use autoresizing masks and it would resize to the correct proportions when the frame changes.

Related

How to convert from iPAD/iPAD2 layout to iPhone4/iPhone5/iPAD-mini layout

I never used Interface Builder ever in my app, and don't think it is something good to do.
My app was already designed for iPad/iPad2 layout, without ever considering making it work on iPhone4/iPhone5/iPAD-mini. Now I want my app to work on all of them.
I think it would be extremely ugly to have 4+ layout the universal app, like this:
if(ipad or ipad2)
view.frame = CGRectMake(0,0,100,100);
else if(ipad-mini)
view.frame = CGRectMake(0,0,100,100);
else if(iphone4)
view.frame = CGRectMake(0,0,100,100);
else if(iphone5)
view.frame = CGRectMake(0,0,100,100);
else if(iphone6)
view.frame = CGRectMake(0,0,100,100);
else if(iphone7)
view.frame = CGRectMake(0,0,100,100);
There should be only 2 layout ideally, but I don't know how to implement this way. Those fixed coordinates would not stretch on different screen sizes
if(ipad or ipad2 or ipad-mini)
view.frame = CGRectMake(0,0,100,100);
else if(iphone4 or iphone5 or iphone6 or iphone7)
view.frame = CGRectMake(0,0,100,100);
How do I do a universal app in the best way?
when you started building this app you should have done soemthing like this:
view.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
and you change above options according to your needs.
and yes you would need different for ipad, iphone
First of all, your layout for iPhone will almost certainly be drastically different from iPad. For the iPads, all the different types have the same aspect ratio, so all you need to worry about is having the #2x images for the iPad with retina.
For the iPhone, however, you have the iPhone 4/4s VS the iPhone 5. Also, you have a lot less screen space, so you will need to find ways to present the same information in a smaller space. This can be done using scrollviews, tableViews, and having one part of the information in one viewController that you can switch to from another viewController.
Finally, I would highly recommend interface builder for most cases. It takes care of iPhone vs iPhone 5, and portrait vs landscape for you. It will even automatically animate the transition when rotating the phone. Sometimes, however, when you need to do custom drawing or our layout is really hard to get with interface builder, it is better to do it programmatically. In that case, a good way to check which device would be by checking the size of [[UIScreen mainScreen] applicationFrame]. Check that with the values of 1024x768 for an iPad, 320x480 for iPhone, or 320x568 for iPhone 5.
However, you really should use interface builder (for most cases). Why exactly do you want to avoid it?

Making application compatible with iPhone4 and iPhone5 without setting diffrent frame size

Today i am going to create an iphone application which is compatible with iphone4 and iphone5. Earlier i have changed iphone4 application views programetically by using below code to adjust controllers for iphone5.
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
// code for iphone5
}
else {
// code for iphone4
}
am thinking this is difficult to track all the frames and sizes of controllers each and every time. I have created one sample app and also tried with Auto-resizing option(i have put check mark) at the starting of view and selected size Retina 4 full screen in inspector. And also selected simulator hardware-device is iphone Retina-4 inch
if i change simulator hardware-device is iphone Retina-3.5 inch then the screen is looking like
My question is without setting frames how can i achieve this problem.
Please help me.
Thanks in advance.
You can use this link for autosizing
http://blog.mugunthkumar.com/coding/supporting-the-iphone-5/
Instead of giving static numbers give frames dynamically. means instead of giving 320 give self.view.frame.size.width so you no need to check the device, just you need to add default splash screen.
You problem could be resolved easily using Autolayout feature provided in the XCode Version 4.x .
Go through the following link :-
http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
By applying few contraints using Autolayout your problem could easily be resolved.
Happy Coding :)

iPhone 5 Optimisation

I'm super confused about how the iPhone 4 and below apps are optimised for the iPhone 5. I'm a designer. How is optimisation done? Basically I have an app with loads of knobs and buttons and other interactive components. The way I see it, there are 3 options but what is the best way (or least, standard practice)?
1) Keep the layout the same for iPhone 5 but just add extra length on the background.
2) Scale the images/layout of components from iPhone 4 to iPhone 5 so everything is proportional.
3) Have completely separate images and different layouts for both. i.e for iPhone 5, I can move components to utilise the space more. The problem with this (and I'm not a developer) is that the interaction position of the components have moved so in effect, the iPhone 4 and 5 are separate apps?
To identify if it is a iphone 5 iphone, use this code in the file nameYourApp-prefix.pch:
//Macro iPhone5
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
find the nameYourApp-prefix.pch file in the supporting files, the code must be written between:
# ifdef __ OBJC__
//Code Macro iPhone5
# endif
and then just use the "if" to check that device, like this:
if (IS_IPHONE_5) {
//Code for 4 inch screen
}else{
//Code for 3.5 inch screen
}
putting the macro in the nameYourApp-prefix.pch, all classes see it.
With a UIKit application, none of your options are ideal. You simply use Springs and Struts or Auto Layout to have your user interface elements snap to where they should be.
The solution is the same when switching between portrait and landscape orientation. You define which user interface elements can grow and which ones can't, which edges to snap to, etc.
Run it on the simulator to test the layout if you don't have an iPhone 5 device.
For example, for a UITableViewController, the UITableView should grow vertically on an iPhone 5 so that you see more rows.
I almost always have at least one control that would be nice to grow given the room. If you don't, then you'll probably just have more empty space at the bottom of the view.
How iPhone 5 Optimization Works
When you tell iOS that your app is optimized for the iPhone 5 (through use of a cleverly named image file), iOS uses your existing Springs and Struts or Auto Layout (whatever you're using) to rearrange the interface.
The first choice is the easiest and works pretty well. You'd only need to worry about having specific assets for full screen images, and make sure that NavigationBar and TabBar (in case your app have one), remains on top and bottom respectively.
Scaling other images/components such as buttons, you'll change the general aspect ratio (which you probably wouldn't want), since iPhone 4&5 display sizes only differ in height.
For developing app option two is better. Although you dont have to change all the images for iPhone 5 some images will me same like TabBarItem. But you have to create background image different for iPhone4 and 5.
Read out this apple document to create user interface.
And you can differentiate iPhone 4 from iPhone 5 using this code
UIBtton * btn = [[UIButton alloc] init];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568)
{
btn.frame = CGRectMake(60,60, 205, 175);
//this is for iPhone5
}
else
{
btn.frame = CGRectMake(60,50, 199, 170);
//this is for iPhone4
}
Here my button place and length are different for iPhone 5 and iPhone 4
And set your control's hight and width according to iPhone Screen Size.
If you didn't, adjust your view layouts with proper auto resizing masks or look into Auto Layout if you only want to support iOS 6 going forward. You have to check height of [[UIScreen mainScreen] bounds].
Example:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
// code for 4-inch screen (iPhone 5)
} else {
// code for 3.5-inch screen (< iPhone 5)
}
Note that [UIImage imageNamed:#"yourImage.png"] will only load either "background.png" or "yourImage#2x.png", it will not load "yourImage-568h#2x.png" if it exists.
Check Auto-Rotation API as Well.

2 XIB and 1 viewcontroller but functions don't work in the ipad XIB

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.

Block AirPlay Mirroring on iOS 5

On iOS 5 with an iPad 2 or iPhone 4S, users can enable screen mirroring with their Apple TV and AirPlay. How can I prevent my app from being mirrored in this way? Is there any way to detect that this mirroring is taking place so I can prevent my content from being mirrored?
The reason for doing this is because I have content I'm not legally allowed to display on a television screen.
This is a really really bad idea and I hate it as you are inhibiting your users. With that said, AirPlay mirroring works the same way as connecting the VGA/HDMI adapter, when you connect an adapter you have the ability to display whatever you want on the "second monitor". If you want to "block" mirroring you could set the external display's window to a blank/solid black view.
Most iOS applications create and use only one window during their lifetime. This window spans the entire main screen of the device and is loaded from the application’s main nib file (or created programmatically) early in the life of the application. However, if an application supports the use of an external display for video out, it can create an additional window to display content on that external display. All other windows are typically created by the system, and are usually created in response to specific events, such as an incoming phone call.
Check out the View Programming Guide for iOS, specifically the Windows section and Displaying Content on an External Display
Just to add the code for doing this pretty simple work Here
if ([[UIScreen screens] count] > 1)
{
UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
CGRect screenBounds = secondScreen.bounds;
UIWindow *secondWindow = [[UIWindow alloc]initWithFrame:screenBounds];
secondWindow.screen = secondScreen;
UIView *anyView= [[UIView alloc]initWithFrame:screenBounds];
anyView.backgroundColor= [UIColor blackColor];
[secondWindow addSubview:anyView];
}