My application is on iPhone in portratit mode. I have also iPad version, that can rotate. Now, with new iPhone 6+, I would like to rotate my app. I have found any problems / solutions regarding this issue.
There are two ways that I can think of
a) better solution (imho) - enable rotation only for certain device. Can it be done without editing code somewhere in project setting ?
b) use iPad version of storyboard on iPhone6+ instead of classic iPhone version of storybaod. Can it be done from within XCode storyboard or project settings, or do I have to do this in my code? I have found no other solution, that to load certain storyboard in code based on device identification.
Here's an easy way to accomplish this. Just add the following to your UIApplicationDelegate:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
static UIInterfaceOrientationMask rv = 0;
if( rv == 0 ) {
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ) {
CGSize s = window.bounds.size;
if( MAX( s.width, s.height ) >= 700.0f ) {
rv = UIInterfaceOrientationMaskAllButUpsideDown;
} else {
rv = UIInterfaceOrientationMaskPortrait;
}
} else {
rv = UIInterfaceOrientationMaskAll;
}
}
return rv;
}
The Apple recommended approach is to combine both iPhone and iPad storyboards into one and use Size Classes in that storyboards to change constraints based on the device/orientation.
As for enabling rotation in particular device - again you might check size classes inside your view controller or check for specific devices resolution. I don't think there is way to enable/disable it for device classes (iPhone 6 vs iPhone 6+) in the project settings.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to detect iPhone 5 (widescreen devices)?
Is there a way I can detect if the current device is the iphone 5? More specifically if it's using the new 4" screen?
Use this
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
I think you should concentrate on preferred display mode, rather than detecting iPhone5. Who knows what devices Apple will manufacture, but if your software supports that mode, it will be futureproof.
BOOL isiPhone5 = CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size,CGSizeMake(640, 1136));
In the future, folks might want to change preferred display mode on the fly. For example disconnect AppleTV from 720p tv and plug to 1080p, without restarting the app of course.
Add this code in your initializtion:
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
if(UIScreenOverscanCompensationScale==1136/640){
//move to your iphone5 storyboard
[UIStoryboard storyboardWithName:(NSString *) bundle (NSBundle *)];
}
else{
//move to your iphone4s storyboard
[UIStoryboard storyboardWithName:(NSString *) bundle (NSBundle *)];
}
}
This was an answer posted by me in another question here.
Add this code to your application:
if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f)
{// iPhone 5 code}
else
{// previous version code}
I updated to Xcode 4.5 and am working with iOS6--a mistake I will definitely not make next time there's an update; it's been sort of nightmarish for somebody so new to iOS--and I've just noticed an app I'm working on is autorotating. I never noticed it autorotatin before the update, but it's also possible I just didn't rotate the phone while testing, so I can't be sure. I've added the following code to the main UIViewController and it's still rotating:
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return NO;
}
Is this the right way to disable autorotation? If it is, then maybe there's some change in iOS6 and I'll have to wait until the full release to find out. But if I've gotten it wrong, what code should I use instead?
Thanks, as always, for your help.
EDIT: Here's the code I changed it to, but it's still rotating. Have I gotten it wrong?
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
return YES;
}
else
{
return NO;
}
}
that is because there was never a success. You should choose one of the orientations.
Hold command and click on UIInterfaceOrientation you will see an enumeration of the possible options.
then you can test against those to decide your YES Scenario.
I may have originally misunderstood your problem. It seems that you may have been saying that your app is allowing rotation. but the code should disallow that.
I was thinking you were saying it was still firing the code. Trying to find a Yes
One thing to think about. is there may be more than one view controller available. perhaps your code is not being hit.
A couple of possible issues for this.
Your code is not even being used. because the view is being allocated as UIViewController as opposed to your custom view controller.
You code is being used but that View controller is not the one being asked about the Orientation. therefore that specific code is not being hit.
A bad build keeps putting the wrong assemblies onto the device.
Your solutions can be as follows.
Ensure your code is the one being allocated. Either there is a direct alloc on your custom class. or the xib file is inflating it. Check out the Identity Inspector when you have your xib file open. select your View Controller and ensure that custom class is set to your class type
Look at the hierarchy. what other view controllers are there. Perhaps one of those are telling the app it can autorotate to any orientation.
Find your "DerivedData" folder and remove it entirely. Sometimes this works from the organizer. other times you need to delete directly off the disk. Then clean and build again.
Also another solution could be as simple as setting the settings in the Project file.
Select your project file from the file browser and you will see the iPad and iPod settings in the summary. You can "UnPress" buttons for the orientations that you want to disallow. and any view controllers that you do not otherwise code orientation into. will use these by default.
My apologies for the confusion.
Update
I commonly use this code to handle my autorotation.
It not only differentiates the ipad from the other ios devices, but it also forwards the request onto presented controllers so a view that is shown modal may respond how it wants.
Orientation is a pain when you dont understand it :)
// Detect iPad
#define IS_IPAD() ([[UIDevice currentDevice] respondsToSelector:#selector(userInterfaceIdiom)] ? \
[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad : NO)
// Set preferred orientation for initial display
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
if (IS_IPAD()){
return UIInterfaceOrientationLandscapeRight;
}
else {
return UIInterfaceOrientationPortrait;
}
}
// Return list of supported orientations.
- (NSUInteger)supportedInterfaceOrientations{
if (self.presentedViewController != nil){
return [self.presentedViewController supportedInterfaceOrientations];
}
else {
if (IS_IPAD()){
return UIInterfaceOrientationMaskLandscapeRight;
}
else {
return UIInterfaceOrientationMaskAll;
}
}
}
// Determine iOS 6 Autorotation.
- (BOOL)shouldAutorotate{
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
// Return yes to allow the device to load initially.
if (orientation == UIDeviceOrientationUnknown) return YES;
// Pass iOS 6 Request for orientation on to iOS 5 code. (backwards compatible)
BOOL result = [self shouldAutorotateToInterfaceOrientation:orientation];
return result;
}
// handle iOS 5 Orientation as normal
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
// Return YES for supported orientations
if (self.presentedViewController != nil){
return [self.presentedViewController shouldAutorotate];
}
else {
if (IS_IPAD()){
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
else {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
}
}
Rotation APIs have changed in iOS6. The new API's are apparently supposed to be opt in however they seem to be enabled for all debug builds on simulator or device. To register for the new API calls throw something like this in your APP Delegates didFinishLoading method.
//Register for new API rotation calls
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"UIApplicationSupportedInterfaceOrientationsIsEnabled"];
At the heart of the rotation changes are two methods (theres a third but Im still figuring this out myself)
- (BOOL)shouldAutorotate
- (NSUInteger)supportedInterfaceOrientations
You need to override these methods in your windows rootViewController. This means you need to subclass UINavigationController or UITabBarController if either is your root controller (this seems bizarre to me, but Apple says Jump).
Now if all you want to do is keep your app in portrait implement the two methods and you're golden.
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Note that apple has further added to the confusion by adding interface orientation masks, ie. UIInterfaceOrientationMaskPortrait != UIInterfaceOrientationPortrait. If you return UIInterfaceOrientationPortrait instead the behaviour will be different. Also you can combine masks the same way you combine orientations so if you wanted to support both portrait orientations you could use.
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
That should work for forcing a portrait orientation. Now if you if you want do do something like allow a child controller to use a different orientation I have no clue.
A very simple way to handle autorotation in both iOS6 and iOS5 is to use supportedInterfaceOrientations & shouldAutorotateToInterfaceOrientation. There are some macros to make it just a line of code. UIInterfaceOrientationIsLandscape & UIInterfaceOrientationMaskLandscape.
I discovered UIInterfaceOrientationMaskLandscape & UIInterfaceOrientationMaskPortrait by auto-completion in xCode. It is not in the Apple docs about autorotation.
Add this code block to your root ViewController to force it to support only landscape mode.
//iOS6 code to support orientations
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskLandscape);
}
//iOS5 code to support orientations
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
return (UIInterfaceOrientationIsLandscape(orientation));
}
For iOS6 you can use the following to detect orientation:
UIInterfaceOrientationMaskLandscape
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskPortraitUpsideDown
UIInterfaceOrientationMaskAllButUpsideDown
UIInterfaceOrientationMaskAll
For iOS5 and below you can use the following to detect orientation:
UIInterfaceOrientationIsLandscape (A macro)
UIInterfaceOrientationIsPortrait
UIInterfaceOrientationIsLandscapeRight
UIInterfaceOrientationIsLandscapeLeft
UIInterfaceOrientationIsPortraitUpsideDown
My app has been in the AppStore for a couple of months now and always only worked on iPhone. I recently submitted an update which was rejected because the App does not run on an iPad. The exact reason it was rejected was:
Reasons for Rejection:
2.10: iPhone apps must also run on iPad without modification, at iPhone resolution, and at 2X iPhone 3GS resolution
What do I need to do in Xcode to make my app run on an iPad in the little box with the 2X icon?
Any tips instructions will be massively appreciated...
EDIT
This is my info.plist. This is my first App and I think I did initially chose to set it up with "universal" selected. Is there an easy way back for me to rectify this now?
Start by figuring out why your app doesn't work on the iPad already. Most apps developed for the iPhone will work fine on an iPad (in compatibility mode) with no modification; if yours doesn't, you must be doing something to prevent it. Are you relying on some hardware feature? Making unfounded assumptions about the device you're running on? How does your app fail when run on an iPad?
Once you've figured out why it doesn't work, you'll be much closer than you are now to fixing the problem.
To get your app to run on an iPad in iPhone compatibility mode, you need to build your app for iPhone only.
Remove all the iPad references from the app's plist (nib base, xib and storyboard), and from the Target Build Settings Targeted Device Family.
I had the same issue, I was able to run my app on the ipad after making the following changes.
in the project settings made the Devices to iPhone(it was universal before)
in the .plist removed the main story board file base name related to ipad.
I have solved same issue using this scenario.
You should check for normal and retina images in your resources folder.
You may also get this error while debugging Could not load the "image.png" image referenced from a nib in the bundle with identifier.
A normal iPhone app must run on the iPad in both(1x and 2x) mode without modification. You can check this with the SDK Simulator.
There is a long list in the App Store Review Guidelines on Apple's iOS Developer Portal Center which lists many of the things that Apple reviews this things when you submit an app. Read it carefully.
I'll try to explain what my problem and solution was..
I have an iPhone only app which is mostly in portrait, however, because of 1 or 2 UIViewControllers which have to be in all UIInterfaceOrientations, I have to enable all UIInterfaceOrientations in my plist.
When starting the app on an iPad which is rotated in landscape and is lying on the table (so has UIDeviceOrientationFaceUp), the whole app was shown in landscape, which made my UI totally messed up.
I had no reference to any iPad related code / settings in my plist or launch screens whatsoever (I am using .xcassets for launch screens).
I fixed it by adding 1 line of code to my AppDelegate.m which sets the statusbar orientation to force the app in portrait mode.
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
//Further setup
}
I had the same issue using Cocos2d 2.0
My problem was that the project had evolved over several years and had carried along some now vestigial files like RootViewController and UIViewController and MyRootViewController, etc.
They worked at the time but clearly had raised a flag with today's review committee because I received the "All iPhone apps must work on the iPad" rejection notice. After screaming out loud and finally accepting defeat, I thought that policy makes it pretty hard to make an app iPhone only. Let me know if I am wrong about this.
Even though I was (and am still) perturbed about it, I thought perhaps now I could at least clean up the project with a more elegant solution that handles the base problem: device rotation + content rotation. I ended up using something from a more recent project that was working on and seemed more elegant and actually worked: simply add MyNavigationController to the top of my AppDelegate.
I have added the code below. I am sure it can be improved. Please comment if you can enhance it.
As a result, I was able to delete the old RootViewController and MyRootViewController files so now it's easier to maintain. I never understood their purpose very well anyways. Good riddance!
Here is my solution to displaying and matching device orientation + content orientation:
in AppDelegate.h I had to declare what I was doing:
//top of the file
#interface MyNavigationController : UINavigationController
#end
//inside AppDelegate.h interface
MyNavigationController *navController_;
//bottom of the file before #end
#property (readonly) MyNavigationController *navController;
Here is the code that works at the top of my AppDelegate.m
#implementation MyNavigationController
// The available orientations should be defined in the Info.plist file.
// And in iOS 6+ only, you can override it in the Root View controller in the "supportedInterfaceOrientations" method.
// Only valid for iOS 6+. NOT VALID for iOS 4 / 5.
-(NSUInteger)supportedInterfaceOrientations {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// [director_ pushScene: [IPAD scene]];
} else {
[[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];
return UIInterfaceOrientationMaskPortrait;
}
} else if (orientation == UIDeviceOrientationLandscapeLeft) {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// [director_ pushScene: [IPAD scene]];
} else {
[[CCDirectorIOS sharedDirector] pushScene:[MainMenuScene scene]];
}
} else if (orientation == UIDeviceOrientationLandscapeRight) {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// [director_ pushScene: [IPAD scene]];
} else {
[[CCDirectorIOS sharedDirector] pushScene:[MainMenuScene scene]];
}
} else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
} else {
[[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];
return UIInterfaceOrientationMaskPortraitUpsideDown;
}
} else {
//do nothing
}
return UIInterfaceOrientationMaskLandscape;
}
//this is the one for iOS 6
- (BOOL)shouldAutorotate {
//NSLog(#"MyNavigationController - should Rotate ToInterfaceOrientation ...");
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
// iPhone only
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ) {
//NSLog(#"MyNavigationController - should Rotate iPhone");
if (orientation == UIDeviceOrientationPortrait) {
//NSLog(#"should Rotate iPhone orientation is Portrait");
[[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];
return UIInterfaceOrientationMaskPortrait;
}
if (orientation == UIDeviceOrientationPortraitUpsideDown) {
//NSLog(#"should Rotate iPhone orientation is PortraitUpsideDown");
[[CCDirectorIOS sharedDirector] pushScene:[VerticalDisplayLayer scene]];
return UIInterfaceOrientationMaskPortraitUpsideDown;
}
if (orientation == UIDeviceOrientationLandscapeLeft) {
//NSLog(#"should Rotate iPhone orientation is Landscape Left");
return UIInterfaceOrientationMaskLandscape;
}
if (orientation == UIDeviceOrientationLandscapeRight) {
//NSLog(#"should Rotate iPhone orientation is Landscape Right");
return UIInterfaceOrientationMaskLandscape;
}
return TRUE;
}
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ) {
//NSLog(#"MyNavigationController - should Rotate iPad");
return TRUE;
}
return TRUE;
}
// Supported orientations. Customize it for your own needs
// Only valid on iOS 4 / 5. NOT VALID for iOS 6.
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
// iPhone only
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone )
return TRUE;
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);
if( [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad )
return TRUE;
// iPad only
// iPhone only
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);
return TRUE;
}
// This is needed for iOS4 and iOS5 in order to ensure
// that the 1st scene has the correct dimensions
// This is not needed on iOS6 and could be added to the application:didFinish...
-(void) directorDidReshapeProjection:(CCDirector*)director
{
if(director.runningScene == nil) {
// Add the first scene to the stack. The director will draw it immediately into the framebuffer. (Animation is started automatically when the view is displayed.)
// and add the scene to the stack. The director will run it when it automatically when the view is displayed.
[director runWithScene: [MainMenuScene scene]];
}
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// Assuming that the main window has the size of the screen
// BUG: This won't work if the EAGLView is not fullscreen
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect rect = CGRectZero;
//NSLog(#"MyNavigationController - Will RotateToInterfaceOrientation ...");
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
rect = screenRect;
} else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
rect.size = CGSizeMake( screenRect.size.height, screenRect.size.width );
}
CCDirector *director = [CCDirector sharedDirector];
CCGLView *glView = (CCGLView *)[director view];
glView.frame = rect;
}
#end
Here is why I had to solve this:
I needed both Landscape and Portrait modes to display different scenes.
Here are some screenshots that describe the situation
I am writing a universal app for both iphone and ipad. How do I determine if the device is an iPad. I have used this link to determine the iPhone type (3G, 3GS).
Determine device (iPhone, iPod Touch) with iPhone SDK
It is highly recommended that you not do device type detection for determining if the application is running on an iPad, but that you examine either features or the user interface idiom. Many applications that test just for specific device types break when new hardware comes out (which tends to be pretty frequent).
Usually, if you need to determine if an application is running on an iPad, it is because you need to adjust the user interface to match the larger display area of the device. For that, Apple recommends that you check the user interface idiom using code like the following:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// iPad-specific interface here
}
else
{
// iPhone and iPod touch interface here
}
Brad's solution is absolutely right. If you're building a universal app designed to run on iPhones with older OS along with up-to-date iPads and iPhones, you might want to add this code to catch situations where the idiom is not defined.
// If iPhoneOS is 3.2 or greater then __IPHONE_3_2 will be defined
#ifndef __IPHONE_3_2
typedef enum {
UIUserInterfaceIdiomPhone, // iPhone and iPod touch
UIUserInterfaceIdiomPad, // iPad
} UIUserInterfaceIdiom;
#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone
#endif // ifndef __IPHONE_3_2
Here is the best answer I got:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
//iPhone methods
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
//iPad methods
}
try this
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
// etc.
}
else
{
//iphone
}
if ( [(NSString*)[UIDevice currentDevice].model isEqualToString:#"iPad"] ) {
NSLog(#"...in iPad");
} else {
NSLog(#"...in iPhone/iPod");
}
The reason I need to find out is that on an iPad, a UIPickerView has the same height in landscape orientation as it does in portrait. On an iPhone it is different. The iPad programming guide introduces an "idiom" value to UIDevice:
UIDevice* thisDevice = [UIDevice currentDevice];
if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
// iPad
}
else
{
// iPhone
}
which works OK while you're in iPad (3.2) but not iPhone (3.1.3) - so it looks like there also needs to be an ifdef to conditionally compile that check, like:
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200
UIDevice* thisDevice = [UIDevice currentDevice];
if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
// etc.
}
#endif
To me that's starting to look very clumsy. What's a better way?
Checking at runtime (your first way) is completely different from #if at compile time. The preprocessor directives won't give you a universal app.
The preferred way is to use Apple's Macro:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// The device is an iPad running iPhone 3.2 or later.
}
else
{
// The device is an iPhone or iPod touch.
}
Use 3.2 as the base SDK (because the macro is not defined pre 3.2), you can target prior OS versions to get it running on the iPhone.
I'm answering this now (and at this late date) because many of the existing answers are quite old, and the most Up Voted actually appears to be wrong according to Apples current docs (iOS 8.1, 2015)!
To prove my point, this is the comment from Apples header file (always look at the Apple source and headers):
/*The UI_USER_INTERFACE_IDIOM() macro is provided for use when
deploying to a version of the iOS less than 3.2. If the earliest
version of iPhone/iOS that you will be deploying for is 3.2 or
greater, you may use -[UIDevice userInterfaceIdiom] directly.*/
Therefore, the currently APPLE recommended way to detect iPhone vs. iPad, is as follows:
1) (DEPRECATED as of iOS 13) On versions of iOS PRIOR to 3.2, use the Apple provided macro:
// for iPhone use UIUserInterfaceIdiomPhone
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
2) On versions of iOS 3.2 or later, use the property on [UIDevice currentDevice]:
// for iPhone use UIUserInterfaceIdiomPhone
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
I like my isPad() function. Same code but keep it out of sight and in only one place.
My solution (works on 3.2+):
#define IS_IPHONE (!IS_IPAD)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone)
then,
if (IS_IPAD)
// do something
or
if (IS_IPHONE)
// do something else
In Swift use userInterfaceIdiom instance property as-
if UIDevice.current.userInterfaceIdiom == .phone {
print("iPhone")
}
& For other devices -
switch UIDevice.current.userInterfaceIdiom {
case .pad:
print("iPad")
case .phone:
print("iPhone")
case .tv:
print("TV")
case .carPlay:
print("carPlay")
default: break;
}
Put this method in your App Delegate so that you can call it anywhere using [[[UIApplication sharedApplication] delegate] isPad]
-(BOOL)isPad
{
BOOL isPad;
NSRange range = [[[UIDevice currentDevice] model] rangeOfString:#"iPad"];
if(range.location==NSNotFound)
{
isPad=NO;
}
else {
isPad=YES;
}
return isPad;
}
If you are using features that are not backwards compatible, I found the best way for me is to create a #define in the pre-compiled header. Example:
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
#define USING_4_X
#endif
Then in your code, you can do this:
BOOL exists = NO;
#ifdef USING_4_X
exists = [SomeObject someMethod:[url lastPathComponent]];
#else
exists = [SomeObject someMethod:[[url path] lastPathComponent]];
#endif
If
1- you already have the app installed into your device,
2- you change its build settings to be a 'Universal' app,
3- install the app to your device on top of the pre-existing app (without deleting the previous one)
You might find that the solutions provided here to detect iPhone/iPad do not work. First, delete the app that was 'only' for iPad/iPhone and install it fresh to your device.
BOOL isIpad()
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return YES;
}
return NO;
}
extension UIDevice {
var isIPad: Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
}