Custom header files in iOS Universal app - iphone

Can I do something as simple as:
myHeaderFile~iphone.h
myHeaderFile~iPad.h
and then: #import "myHeaderFile.h"
?
I'm assuming no, but you get the idea. Any tips?
If I try using macros it doesn't work, because by the time the macros are parsed, the app is already running. I just need that for loading different definitions for different screen resolutions.

How about something like this instead?
#ifdef UI_USER_INTERFACE_IDIOM()
#define IS_IPAD() (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD() (false)
#endif
Then you can selectively build code like:
if (IS_IPAD()){
// do something for iPad
}
else {
// do something for iPhone/iPod
}

Related

How to create if-else loop near #import sttatement to check the Device Type (iPad/iPhone)

I am using PKRevealController to create SplitView in my app. In PKRevealController.m file i am giving the value to how much screen will reveal using this code
#define DEFAULT_LEFT_VIEW_WIDTH_RANGE NSMakeRange(273, 310)
This is for iPhone but now i want to make loop to select the size. if device is iPad than large else small so how can i do this because its outside of #interface PKRevealController
I have check some code on google and i find like this
#if defined(__IPHONE_6_0) || defined(__MAC_10_8)
#define AF_CAST_TO_BLOCK id
#else
#define AF_CAST_TO_BLOCK __bridge void *
So can i create something like this for selecting device?
You can use this code to achive this change value according to your need
In your PKRevealController.m
#define DEFAULT_LEFT_VIEW_WIDTH_RANGE_iPad NSMakeRange(700, 700)
#define DEFAULT_LEFT_VIEW_WIDTH_RANGE_iPhone NSMakeRange(273, 310)
#define DEFAULT_RIGHT_VIEW_WIDTH_RANGE_iPad DEFAULT_LEFT_VIEW_WIDTH_RANGE_iPad
#define DEFAULT_RIGHT_VIEW_WIDTH_RANGE_iPhone DEFAULT_LEFT_VIEW_WIDTH_RANGE_iPhone
And in iterface find out setup method an replace it with this method
pragma mark - Setup
- (void)setup
{
self.state = PKRevealControllerFocusesFrontViewController;
if ([[UIDevice currentDevice] userInterfaceIdiom] ==UIUserInterfaceIdiomPhone)
{
//device is iPhone
self.leftViewWidthRange = DEFAULT_LEFT_VIEW_WIDTH_RANGE_iPhone;
self.rightViewWidthRange = DEFAULT_RIGHT_VIEW_WIDTH_RANGE_iPhone;
}
else
{
//device is iPad
self.leftViewWidthRange = DEFAULT_LEFT_VIEW_WIDTH_RANGE_iPad;
self.rightViewWidthRange = DEFAULT_RIGHT_VIEW_WIDTH_RANGE_iPad;
}
self.view.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
}
Than it should be work..:)
I don't really think there is a way to do that, usually problem like that is solved by making 2 #define statements, like this:
#define DEFAULT_LEFT_VIEW_WIDTH_RANGE_IPHONE NSMakeRange(273, 310)
#define DEFAULT_LEFT_VIEW_WIDTH_RANGE_IPAD NSMakeRange(273, 310)
and then when you have to use it in code just check the device type like this:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
/* code that uses DEFAULT_LEFT_VIEW_WIDTH_RANGE_IPAD */
}
else {
/* code that uses DEFAULT_LEFT_VIEW_WIDTH_RANGE_IPHONE */
}

Define constant based on device type

I have a Constants.h file which contains some global constants in fact. Since my application is built both for iPhone and iPad, i would like to define the same constants (ie with the same name) differently for the two device types.
For a complete explanation:
/******** pseudo code *********/
if (deviceIsIPad){
#define kPageMargin 20
}
else {
#define kPageMargin 10
}
How can I do this?
Thanks.
L.
It's impossible to get device type during preprocessing step. It is determined dynamically during runtime. You have two options:
Create two different targets (for iPhone and iPad respectively) and define macro there.
Create macro that inserts expression like this:
#define IS_IPAD (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
#define kMyConstant1 (IS_IPAD ? 100 : 200)
#define kMyConstant2 (IS_IPAD ? 210 : 230)
#define kMyConstant3 (IS_IPAD ? #"ADASD" : #"XCBX")
#define are resolved at compile time, ie on your computer
Obviously, you can't make them conditional the way you want. I recommend creating static variable and setting them on the +(void)initialise method of your class.
And for the condition, use something like
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// iPad
} else {
// iPhone or iPod touch.
}
So that would go
static NSInteger foo;
#implementation bar
+(void)initialise{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// iPad
foo = 42;
} else {
// iPhone or iPod touch.
foo = 1337;
}
}
#end
Use UIDevice Macros - http://d3signerd.com/tag/uidevice/
Then you can write code like;
if ([DEVICE_TYPE isEqualToString:DEVICE_IPAD]) {
}
or
if (IS_SIMULATOR && IS_RETINA) {
}
You can't do this with defines, as they're expanded at compilation time. However, you can define variables and set their initial value based on the user interface idiom:
// SomeClass.h
extern CGFloat deviceDependentSize;
// SomeClass.m
- (id)init
{
// ...
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad])
deviceDependentSize = 1024.0f; // iPad
else
deviceDependentSize = 480.0f; // iPhone
// etc.
}
Hi write this code in appdelegate class
+(NSString *)isAppRunningOnIpad:(NSString *)strNib{
NSString *strTemp;
NSString *deviceType = [UIDevice currentDevice].model;
if ([deviceType hasPrefix:#"iPad"]){
strTemp=[NSString stringWithFormat:#"%#I",strNib];
}
else{
strTemp=strNib;
}
return strTemp;
}
call this from your class using this line
SecondVC *obj_secondvc = [[SecondVC alloc] initWithNibName:[AppDelegate isAppRunningOnIpad:#"SecondVC"] bundle:nil];

iPhone : How to check device using MACRO?

I want to check whether the device is iPhone or iPad using the macro.
I have a file Constant.h where I have given values using #define.
Now, I want to check device using #ifdef #endif.
Follwing method can be possible only in the .m file.
But I have only one .h only.
- (BOOL) isPad{
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
So above method is not useful for me ?
Is there any way to do this ? Or any other way?
I have simple answer to this question.
#define isiPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? YES : NO)
This will returns 1 if device is iPad and 0 if device is iPod or iPhone.
You can't check it by macro, because macro is expanded during compilation. So you need to know device type at compile time.
If you want to support both devices at runtime, you need to check device type and use appropriate set of constants.
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200
UIDevice* thisDevice = [UIDevice currentDevice];
if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
// etc.
}
#endif

iPhone - How to use #define in Universal app

I'm creating universal app that runs oniphone and ipad.
I'm using #define to create CGRect. And I want to use two different #define - one for iPhone and one for iPad.
How can I declare them so that correct one will be picked by universal app..........
I think I've to update little more description to avoid confusion.
I've a WPConstants.h file where I'm declaring all the #define as below
#define PUZZLE_TOPVIEW_RECT CGRectMake(0, 0, 480, 100)
#define PUZZLE_MIDDLEVIEW_RECT CGRectMake(0, 100, 480, 100)
#define PUZZLE_BOTTOMVIEW_RECT CGRectMake(0, 200, 480, 100)
The above ones are for iphone. Similarly for iPad I want to have different #define
How can I proceed further?
As recommended by Apple, use
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { ... }
else { ... }
to write platform-specific code. With the ternary ?: operator, you could also incorporate this into a #define:
#define MyRect (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? CGRectMake(0,0,1024,768) : CGRectMake(0,0,480,320))
In case you wanted to use conditional compilation to determine which of two #define statements should be included in your code, you can't: a universal app does not contain two separate binaries for iPhone and iPad. It's just one binary so all platform-related decisions have to be made at runtime.
i used this function to detect iPad, and then write conditions for all different parts of my application.
#ifdef UI_USER_INTERFACE_IDIOM
#define isPad() (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define isPad() NO
#endif
Also you can load different xib files for iPhone/iPad.

Best way to programmatically detect iPad/iPhone hardware

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
}
}