How to define variable depend on condition in XCode - iphone

I want to define some variables depend on whether it is run on Iphone or Ipad application. So I wrote this code
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
#define ABC #"122"
NSLog(#"Ipad");
} else {
#define ABC #"123"
NSLog(#"iphone ");
}
NSLog(#" %#", ABC);
But in both iphone and Ipad it show 123.

Try this out:
#define ABC (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? #"122" : #"123")
This should work fine for you.

#define tells the preprocessor to modify every occurrence of ABC in the source code by the value associated with it.
ABC will be substituted with #"122" in all the lines that follow the line #define ABC #"122" and by #"123" in all the lines that follow the line #define ABC #"123".
This step happens at build time and not runtime. So you should define ABC as a string and set its value as follows:
NSString *ABC;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
ABC = #"122";
NSLog(#"Ipad");
} else {
ABC = #"123";
NSLog(#"iphone ");
}
NSLog(#"%#", ABC);

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

ifdef syntax doesn't work

I want dynamically define a constant based on the different device heights.
I tried to use this code but it doesn't work:
#define isPhone568 ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568)
#ifdef isPhone568
#define kColumnHeightPortrait568 548
#else
#define kColumnHeightPortrait568 (IS_IPAD ? 984 : 460)
#endif
Even if i'm using the 3.5" simulator, i get 548. What's wrong with this?
You can't run code in macro definitions, it's a simple text substitution process that happens at compile-time. Hence you have no idea what the device characteristics are at that point, because you're not on the target device.
If you want to use something like [UIDevice currentDevice] userInterfaceIdiom, you have to evaluate it at run-time, not in a compile-time macro, something like:
int kColumnHeightPortrait568 = 548;
if (([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPhone)
|| ([UIScreen mainScreen].bounds.size.height != 568))
{
kColumnHeightPortrait568 = (IS_IPAD ? 984 : 460);
}
The #ifdef is used to check whether a macro is defined. As you define isPhone568 in the first line, #ifdef isPhone568 will be true.
If you want to test the value of an expression rather than the existance of a macro, you should use #if instead. But #if can test no more than the simple arithmetic expression, just as paxdiablo mentioned, "You can't run code in macro definitions".

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];

#ifdef conditionals not working

I am using conditional code as below,
I want to run certain code only in ios5.0 and > ios5.0( i mean i want to support ios5.0 and 5.1 version too)
But the below condition dos not seem to work. ( Currently my development version is 5.1 but the below snippet is not getting identified.the control is not going into it.)
Please let me know your thoughts
#ifdef __IPHONE_5_0_OR_LATER
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_5_0
// iPhone 5.0 code here
#endif
#define __IPHONE_2_0 20000
#define __IPHONE_2_1 20100
#define __IPHONE_2_2 20200
#define __IPHONE_3_0 30000
#define __IPHONE_3_1 30100
#define __IPHONE_3_2 30200
#define __IPHONE_4_0 40000
#define __IPHONE_4_1 40100
#define __IPHONE_4_2 40200
#define __IPHONE_4_3 40300
#define __IPHONE_5_0 50000
#define __IPHONE_5_1 50100
#define __IPHONE_NA 99999 /* not available */
How to target a specific iPhone version?
#ifdef is a compile directive, thus it will be evaluated at compile time not run time.
Thus if you add this to you code, the methods call in the if will all ways be called if your target SDK matches your #ifdef. So if you compile an app for both iOS 4 and 5 and place all the 5 only methods in #ifdef io5 the app will crash on iOS 4 since the methods will be called.
If you want to check if some method is available then you should do like :
Here is an example for dismissing an modal view controller from it's parent. Since parentViewController is changed to presentingViewController in iOS 5, we check if presentingViewController is available and use it.
if ([self respondsToSelector:#selector(presentingViewController)]) {
[self.presentingViewController dismissModalViewControllerAnimated:YES];
} else {
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
The same with goes for checking if a class is available :
if ([MPNowPlayingInfoCenter class]) {
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSDictionary *songInfo = /* ... snip ... */;
center.nowPlayingInfo = songInfo;
}
NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
if ( 5 == [[versionCompatibility objectAtIndex:0] intValue] ) { /// iOS5 is installed
// Put iOS-5 code here
} else { /// iOS4 is installed
// Put iOS-4 code here
}

iPhone - iPad Device Type Trick in the Header File

So I've got a function that really helps when I'm crafting device specific URLS but I'd like to place it in a global header file so any class could use it easily
- (NSString *)deviceType
{
NSString *deviceName = #"iphone";
if([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
deviceName = #"ipad";
}
else {
deviceName = #"iphone4";
}
}
return deviceName;
}
That may or may not be the best way of doing it but I'd like to know how to get that into a global header so I can do something like this
NSString *deviceName = GETDEVICENAME;
#define GETDEVICENAME [whatever deviceType] maybe?
There is an issue with your function though, on 3.2 UIScreen doesn't respond to scale (at least no publicly. I wouldn't rely on that to check for iPad.
With in your project should be a file called %PROJECT%_Prefix.pch.
Any headers you include in that file will be accessible by all files in your project.
Got the answer that worked for me,
In a global header file Globals.h I placed
NSString* deviceType();
in Globals.m I placed a modified function
NSString* deviceType()
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
return #"ipad";
}
else if([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
{
return #"iphone4";
}
else{
return #"iphone";
}
}