How can I determine if the device that is running my app is ios 5?
I'm trying to use the UIAppearance class but it will give an error if it's running on ios versions other than 5. so I want to have if statement that only runs this line of code if the device is ios5.
Thanks,
EDIT:
SO here is the solution,
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 5.0){
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
You can get the OS version using
[[UIDevice currentDevice] systemVersion]
But a better way would be to check for specific features, Something along the lines of
if(NSProtocolFromString(#"UIAppearance")) {
// Do something
}
To see if that class is available, then perform you operations.
Failing that it is also possible to make sure you only build for iOS 5, and it will only install on iOS 5 devices.
Related
UIView of my app appears fine in ios6 but when it comes to ios7 the entire view is distorted. In ios7 the whole view is lifted upwards.
EDIT :
Then I applied this code:
float SystemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(SystemVersion<7.0f)
{
//Currently your app is running in IOS6 or older version. So you need not to do anything.
}
else
{
// Currently your app is running in IOS7. Do the following.
CGRect TempRect;
for(UIView *sub in [[self view] subviews])
{
TempRect=[sub frame];
TempRect.origin.y+=20.0f; //Height of status bar
[sub setFrame:TempRect];
}
}
but still there is no change. How do I resolve this?
Try this way..
IOS & DISPLAY
OR
This..
Status Bar Issue
This way make the your All subviews as +20 pixels i.e.Increase the +20 of y-axis for all views
Set the deleta for the ios 7. so, it will display the good in both ios 6 & 7.
//Give it frame if navigation bar and status bar both displaying on screen
// first check if device have ios 7
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
self.view.frame=CGRectMake(0,64,320,self.view.height);
}
try my answer...write that code in ViewdidLoad method..
Status Bar issue
Happy Coding!!!
Please see below note
Using xcode 5,
click on xib,Go to file inspector and change setting as below
Deployment target as ios 7
here,You need to crate two xib view based on view as ios 7 and later and view as ios 6 and earlier and white condition based on xib call
Define below code in .m file
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
if view as IOS 7.0 and later
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
//Here call ios 7 xib
}else{
//Here call ios 6 and earlier xib
}
You have to create two xib for ios6 and ios7.
than You have to check condition if device is of ios7 than call ios7 xib otherwise go for ios6.
My navigation bar colours appear normally in iOS 7
Deploying iOS 6.0, but if the system version is iOS 7.0 or later, some of the navigation bar colouring doesn't display properly on iPhone 4. Works fine in iPhone 5.
Here's how I am doing it:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
self.edgesForExtendedLayout = UIRectEdgeNone;
[self.navigationController.navigationBar setBarTintColor:[UIColor blueColor]];
[self.navigationController.navigationBar setTranslucent:YES];
}
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
Maybe the last line is the problem (setTranslucent) since I have heard that iPhone 4 has some problems with the translucency, but I'm pretty sure that you could set the navbar to be translucent in iOS 6 as well. Will try getting rid of that out next and update if it fixes anything.
EDIT:
Looks like the bar colour disappears after I dismiss a presented view controller. But it doesn't screw up on anything but the iPhone 4.
Get rid of [self.navigationController.navigationBar setTranslucent:YES]; and it should work fine.
If you want, you can check the device model
(see here: Determine device (iPhone, iPod Touch) with iPhone SDK)
and adjust view accordingly.
I want to implement connect to twitter functionality for iOS 5 and iOS 6. What would be the best way to integrate solution for both way?
Please let me know your thoughts.
Thanks,
Jim.
You can get the IOS version using:
[[UIDevice currentDevice] systemVersion]
For example check like this which IOS version it is and use according to your requirement:
if([[[UIDevice currentDevice] systemVersion] isEqualToString:#"5.0"] || [[[UIDevice currentDevice] systemVersion] isEqualToString:#"5.1"])
{
//twitter functionality for iOS 5
}
else if([[[UIDevice currentDevice] systemVersion] isEqualToString:#"6.0"])
{
//twitter functionality for iOS 6
}
I've started playing with iOS 5 today and I've seen that XCode 4.2 only let me select iOS 5 as Base SDK but not iOS 4.
Until now I've overwriting drawRect: method in UINavigationBar to customize its appearance but iOS 5 doesn't call that method anymore. Now I've to use [UINavigationBar appearance] to do it (which I think is much better). However, appearance method is only available in iOS 5 so if I use it my app it crashes when executing on iOS 4. What should I do? Do I have to check iOS version with macros in every place I use a iOS 5 method?
Thank you,
Ariel
The answer to your first question is: You must use iOS5 (or Latest iOS SDK) as your base SDK, but you set your minimum supported iOS version under Deployment Target. There you can set iOS4.0 (or whatever you want).
The correct way to deal with your second question is to test for capability, not version. So, something like this would work in say, your application:didFinishLaunchingWithOptions: method:
// iOS5-only to customize the nav bar appearance
if ([[UINavigationBar class] respondsToSelector:#selector(appearance)]) {
UIImage *img = [UIImage imageNamed: #"NavBarBackground.png"];
[[UINavigationBar appearance] setBackgroundImage:img forBarMetrics:UIBarMetricsDefault];
}
You will then be compiling this against the iOS5 SDK, so the use of appearance at all will be fine. But when this compiled code runs on a version of iOS before 5, it will be fine.
As said before, you can keep your drawRect: code as-is.
Another way to customized your header is like this.
UIImage *image = [UIImage imageNamed:#"header.png"];
if([navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] ) {
//iOS 5 new UINavigationBar custom background
[navigationBar setBackgroundImage:image forBarMetrics: UIBarMetricsDefault];
}
else{
UIImageView *imgView = [[[UIImageView alloc] initWithImage:image] autorelease];
[imgView setUserInteractionEnabled:NO];
[imgView setTag:TOOLBAR_TAG];
[navigationBar insertSubview:imgView atIndex:0];
}
Using the respondsToSelector you can know if the function is here.
You can put the same piece of code in both the drawRect: that iOS 4 uses and the proxy returned by [UINavigationbar appearance]. Two different code paths.
You can't do this with macros since both code paths have to be in place and the correct route to go depends on a run-time check.
Soooo... use something like this:
NSString *os_version = [[UIDevice currentDevice] systemVersion];
to get the iOS version you're currently running on and do the [UINavigationBar appearance] under 5 & newer, and you can fall back to the drawRect thing on iOS 4.
Also take advantage of downloading the 4.3 simulators for iPhone and iPad. Then you can crash faster when you accidentally use iOS 5 stuff on 4.3
--Tom
Apple advises using the following code to detect whether running on an iPad or iPhone/iPod Touch:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// The device is an iPad running iPhone 3.2 or later.
// [for example, load appropriate iPad nib file]
}
else {
// The device is an iPhone or iPod touch.
// [for example, load appropriate iPhone nib file]
}
The problem is that UI_USER_INTERFACE_IDIOM() and UIUserInterfaceIdiomPad are NOT defined in the SDKs prior to 3.2. This seems to completely defeat the purpose of such a function. They can only be compiled and run on iPhone OS 3.2 (iPhone OS 3.2 can only be run on iPad). So if you can use UI_USER_INTERFACE_IDIOM(), the result will always be to indicate an iPad.
If you include this code and target OS 3.1.3 (the most recent iPhone/iPod Touch OS) in order to test your iPhone-bound universal app code, you will get compiler errors since the symbols are not defined in 3.1.3 or earlier, when compiling for iPhone simulator 3.1.3.
If this is the recommended-by-Apple approach to runtime device-detection, what am I doing wrong? Has anyone succeeded using this approach to device-detection?
I do this to get the code to compile in both 3.1.3 and 3.2:
BOOL iPad = NO;
#ifdef UI_USER_INTERFACE_IDIOM
iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#endif
if (iPad) {
// iPad specific code here
} else {
// iPhone/iPod specific code here
}
I also wrote a quick blog post about it here:
http://www.programbles.com/2010/04/03/compiling-conditional-code-in-universal-iphone-ipad-applications/
This is what I use:
- (BOOL) amIAnIPad {
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
if ([[UIDevice currentDevice] respondsToSelector: #selector(userInterfaceIdiom)])
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
#endif
return NO;
}
This conditionally compiles, so you can still build for the 3.0 sim. It then checks to see if the UIDevice class responds to the selector. If either of these fail, it's not an iPad.
If this is the recommended-by-Apple approach to runtime
device-detection, what am I doing wrong? Has anyone succeeded using
this approach to device-detection?
This is solution for runtime detection:
#define isIPhone (![[UIDevice currentDevice] respondsToSelector:#selector(userInterfaceIdiom)] || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
After that you can easily test it anywhere in your code:
if (isIPhone) { ... }
The difference between this and using #if / #ifdef is that this is runtime testing, while #if is compile-time testing.
I think the runtime testing is better, because you can use one exactable for any OS version in this case. If you use compile-time check, you'll need to produce different executables for different OS versions.
If your problem is compile-time errors, you just should compile against last version of SDK (see also How to access weak linked framework in iOS?).
I believe the answer is simply do not attempt to run the code on iPhone simulator 3.1.3 or earlier. Always compile with a 3.2 SDK. The iPhone simulator 3.2 will get you the iPad simulator, or compile for iPhone Device 3.2 and put the app on a phone to test it.
There is no way to compile against 3.2 SDK and use a 3.1.3 or earlier simulator.
Instead of any compiler based stuff I use:
- (BOOL)deviceIsAnIPad {
if ([[UIDevice currentDevice] respondsToSelector:#selector(userInterfaceIdiom)])
//We can test if it's an iPad. Running iOS3.2+
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
return YES; //is an iPad
else
return NO; //is an iPhone
else
return NO; //does not respond to selector, therefore must be < iOS3.2, therefore is an iPhone
}
Declare using this
#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif
then use check as below
#define DetailLabel_PosX (IS_IPAD ? 200 : 160)
There are also some define for checking iphone 5
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
#define IOS_OLDER_THAN_6 ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_6 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0 )
This seems to completely defeat the purpose of such a function. They
can only be compiled and run on iPhone
OS 3.2 (iPhone OS 3.2 can only be run
on iPad). So if you can use
UI_USER_INTERFACE_IDIOM(), the result
will always be to indicate an iPad.
This is completely incorrect. It can be compiled on Base SDK of 3.2, but it can be run on any OS, if you set the deployment target appropriately.
UI_USER_INTERFACE_IDIOM() and UIUserInterfaceIdiomPad can be used on iOS3.2 and upwards, the important part being the 'upwards'. Sure. iOS3.2 is only for iPad, but iOS4.0 and beyond run on both iPhones and iPads, so the check isn't as pointless as you think.