I'm a little bit lost in the bitwise ;)
My goal is to retrieve the whole set of orientations supported by an application and to test each result value to update a custom variable.
My problem is that I don't know how to make the comparison (I got a conversion/test problem...)
First I read this article : Testing for bitwise Enum values
But it doesn't bring me the light...
Let say I have the following orientation declare for my application (following is the log output for my variable supportedOrientations) :
supported orientations = (
UIInterfaceOrientationPortrait
)
So my first attempt was to try some test on integer values but it does not work (even if the application is declared to be in portrait mode the test return 'false') :
NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"UISupportedInterfaceOrientations"];
NSLog(#"[supported orientations = %#", supportedOrientations);
// for clarity just make a test on the first orientation we found
if ((NSInteger)supportedOrientations[0] == UIInterfaceOrientationPortrait) {
NSLog(#"We detect Portrait mode!");
}
My second attempt was to try the bitwise thing but this time it always return 'true' (even if the supported orientation is not UIInterfaceOrientationPortrait). :
NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"UISupportedInterfaceOrientations"];
NSLog(#"[supported orientations = %#", supportedOrientations);
// for clarity just make a test on the first orientation we found
if ((NSInteger)supportedOrientations[0] | UIInterfaceOrientationPortrait) { // <-- I also test with UIInterfaceOrientationMaskPortrait but no more success
NSLog(#"We detect Portrait mode!");
}
So my question is :
How to test the orientation in my case?
Is it a way to use a test by using a bitwise thing (using | operand)?
The official doc says that UISupportedInterfaceOrientations is an array of strings.
https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW10
So the solution is to use NSString comparison for each element found in the array.
NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"UISupportedInterfaceOrientations"];
for (NSString *orientation in supportedOrientations) {
if ([orientation isEqualToString:#"UIInterfaceOrientationPortrait"] ||
[orientation isEqualToString:#"UIInterfaceOrientationPortraitUpsideDown"]) {
NSLog(#"*** We detect Portrait mode!");
} else if ([orientation isEqualToString:#"UIInterfaceOrientationLandscapeLeft"] ||
[orientation isEqualToString:#"UIInterfaceOrientationLandscapeRight"]) {
NSLog(#"*** We detect Landscape mode!");
}
}
Note that doing like this we didn't take advantage of the enum values (of type UIInterfaceOrientation), but it works!
Related
I have two scenes - DifficultScene and GameScene. In DifficultScene I have three buttons - easy, medium and hard. I use a global variable Bool to keep track of the current difficulty level. When I try easy mode everything works fine, but when I try medium or hard, bool is changing every second, jumping from hard to medium and easy, making game unplayable. My question is - how can I fix it? Here are code were it happens:
GamesScene.m
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
extern BOOL isEasyMode;
extern BOOL isMediumMode;
extern BOOL isHardMode;
if ((isEasyMode = YES)) {
NSLog(#"easy");
[self computer];
}
if ((isMediumMode = YES)) {
NSLog(#"medium");
[self computerMedium];
}
if ((isHardMode = YES)) {
NSLog(#"hard");
[self computerHard];
}
[self scoreCount];
}
(if more code is needed, i will post it)
I think your update method calls periodically as per timer so it will get called continuously if it so then. Thats why it is happening i think and another major thing is you should use == for comparison. you are using (isEasyMode = YES) that means you are assigning YES to isEasyMode.
So replce all if statement like if ((isEasyMode = YES)) with if (isEasyMode == YES).
Update :
if statement should like,
if (isEasyMode == YES) {
NSLog(#"easy");
[self computer];
}
Hope this will help :)
I want to write a helper class to get values from my info.plist and have them be cast to their correct type. So, if I try to access a property that's actually a number as a date, I should get back nil or an error.
I'm having trouble coming up with a nice way to check the type. I've tried to read [val class]. In the example below, it comes back as __NSTaggedDate for date values, which seems like an implementation detail I don't want to rely on.
- (NSDate *)dateConfig:(NSString *)name
{
_configs = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"myConfigDictionary"];
id val = [_configs objectForKey:name];
// TODO how do I tell?
if([val class] != ???)
{
return nil;
}
return val;
}
I want to do this reliably for all other plist types as well. What's an elegant way to get this done?
You are looking for the message isKindOfClass:
if([val isKindOfClass:[NSNumber class]])
{
return (NSNumber *)val;
}
else
{
return nil;
}
Be aware that there is also isMemberOfClass: but you rarely would want this. Many foundation objects are really Core Foundation based (i.e. NSString is NSCFString most of the time).
spent some time and can't really understand where is a problem.
I'm using GPUImage 0.1.3 (from CocoaPods) and have very straightforward code:
GPUImageiOSBlurFilter *iosBlur = [[GPUImageiOSBlurFilter alloc] init];
UIImage *splashScreenImage = [UIImage imageNamed:#"Splash"];
UIImage *bluredImage = [iosBlur imageByFilteringImage:splashScreenImage];
bluredImage is nil.
I stepped through the code, iosBlur isn't nil, splashScreenImage isn't nil and contains proper image (checked in debugger's quick view). So I don't have any idea where is a problem.
This is how I worked around it - crude, but works.
BTW - this still happens with the latest code of GPUImage, although I mostly see the issue in the simulator.
int errorCount = 0;
UIImage *blurImage;
//Loop workaround for some unknown GPUImage issue where sometimes the result is nil.
while (! (blurImage = [imageFilter imageByFilteringImage:image]) ) {
++errorCount;
}
if (errorCount > 0) {
NSLog(#"GPUImageiOSBlurFilter imageByFilteringImage error count: %i", errorCount);
}
From the GPUImageOutput.h
// Platform-specific image output methods
// If you're trying to use these methods, remember that you need to set -useNextFrameForImageCapture
// before running -processImage or running video and calling any of these methods,
// or you will get a nil image
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
- (UIImage *)imageByFilteringImage:(UIImage *)imageToFilter;
I'm trying to determine the user language in iOS. StackOverflow has several answers on this topic which has greatly helped me out, such as this one: Getting current device language in iOS?
I can successfully retrieve the value I'm looking for in NSLog (i.e. "en" or "de") but every time I question this with an if/then statement it doesn't appear to work. I have this in my viewDidLoad for testing:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *myLanguage = [[NSLocale preferredLanguages] objectAtIndex:0];
NSLog(#"The current languague is %#.", myLanguage);
if (myLanguage == #"de") {
self.myLabel.text = #"German";
} else if (myLanguage == #"en") {
self.myLabel.text = #"English";
} else {
self.myLabel.text = #"didn't work";
}
}
No matter if the device is set to English or German only the last else statement is displayed. NSLog however correctly displays either en or de.
What am I doing wrong?
NSString comparison is done with isEqualToString: method. In your code you are comparing two different NSString objects, while instead you have to compare the contents of each one of them.
If you have two objects of any kind, they are always different, even if all their members have the same values. That's why methods like this exist, to compare objects based on their members.
Replace:
if (myLanguage == #"de")
with
if ([myLanguage isEqualToString:#"de"])
and the same for the else ifs in your code.
Xcode (4) highlights the UISupportedInterfaceOrientations settings, but no matter how I set them, it does not appear to affect a basic app's functionality. The Xcode templates insert commented out implementation for programmatically reporting support in:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
In my experience, this code has nothing to do with the app's bundle settings. So, I wrote the following code to automatically report support for orientation based on the app settings.
Why isn't this the default implementation? Did I miss something and this code shouldn't be necessary? (Any improvements anyone can suggest?) I might turn this into a category for UIViewController
/**
* This implementation coordinates the app's orientation support with the app
* bundle settings, simplifying the configuration of the app's support for its
* different orientations.
*/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
static NSString *_orientationFlagNames[] = {
Nil, // UIDeviceOrientationUnknown
#"UIInterfaceOrientationPortrait", // UIDeviceOrientationPortrait,
#"UIInterfaceOrientationPortraitUpsideDown",// UIDeviceOrientationPortraitUpsideDown,
#"UIInterfaceOrientationLandscapeRight", // UIDeviceOrientationLandscapeLeft [sic]
#"UIInterfaceOrientationLandscapeLeft" // UIDeviceOrientationLandscapeRight [sic]
// UIDeviceOrientationFaceUp
// UIDeviceOrientationFaceDown
};
NSArray *supportedOrientation = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"UISupportedInterfaceOrientations"];
BOOL shouldRotate = (interfaceOrientation < sizeof(_orientationFlagNames)/sizeof(NSString*)
&& [supportedOrientation containsObject:_orientationFlagNames[interfaceOrientation]]);
return shouldRotate;
}
I think there is a distinction here. The info.plist value indicates the orientations that the app supports whereas the shouldAutorotateToInterfaceOrientation: indicates the orientations a particular view is available in.
If you look here, it is clearly mentioned that the info.plist values help iOS choose the initial orientation to launch the application.