How to check multiple Switch case value in Objective-C? - ios

In Swift it is possible to check a tuple like,
switch(type1, type2) {
case (1, 1):
functionNormal()
case (1, 2):
functionUncommon()
case (1, 3):
functionRare()
...
}
Is it possible to check tuple like multiple values in Objective-C Switch case? Any way around?

There could be various approaches, depending on exactly what your type1 and type2 data might be.
However, here is a basic example:
NSInteger i = 1;
NSInteger j = 2;
switch (i) {
case 1:
switch (j) {
case 1:
[self functionNormal];
break;
case 2:
[self functionUncommon];
break;
case 3:
[self functionRare];
break;
default:
NSLog(#"first value: 1 ... missing case for second value: for %ld", (long)j);
break;
}
break;
case 2:
switch (j) {
case 1:
[self secondFunctionNormal];
break;
case 2:
[self secondFunctionUncommon];
break;
case 3:
[self secondFunctionRare];
break;
default:
NSLog(#"first value: 2 ... missing case for second value: %ld", (long)j);
break;
}
break;
default:
NSLog(#"missing first case for first value: %ld", (long)i);
break;
}
This is rather inefficient, of course, but maybe it can get you on your way.
Edit
Again, it will depend on your data, but another approach more closely resembling your Swift example:
NSInteger i = 1;
NSInteger j = 2;
NSInteger ij = i * 1000 + j;
switch (ij) {
case 1001:
[self functionNormal];
break;
case 1002:
[self functionUncommon];
break;
case 1003:
[self functionRare];
break;
case 2001:
[self secondFunctionNormal];
break;
case 2002:
[self secondFunctionUncommon];
break;
case 2003:
[self secondFunctionRare];
break;
default:
NSLog(#"case was something else: %ld", (long)ij);
break;
}

Related

Better way of using arc4random

I have a random method to create 2 random integers. My concern is that %65-%70 of outputs are same integers like "5-5" "4-4" "3-3".
-(void)random{
NSUInteger randomNumber = arc4random_uniform(5);
switch (randomNumber) {
case 0:
_tile2.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile2.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile2.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile2.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile2.image = [UIImage imageNamed:#"five.png"];
break;
}
NSUInteger randomNumber2 = arc4random_uniform(5);
switch (randomNumber2) {
case 0:
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile3.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile3.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile3.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile3.image = [UIImage imageNamed:#"five.png"];
break;
}
}
Should i create 25 different case to reach better result?
NSUInteger randomNumber = arc4random_uniform(25);
switch (randomNumber) {
case 0:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
case 1:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"two.png"];
break;
case 2:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"three.png"];
break;
case 3:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"four.png"];
break;
case 4:
_tile2.image = [UIImage imageNamed:#"one.png"];
_tile3.image = [UIImage imageNamed:#"five.png"];
break;
case 5:
_tile2.image = [UIImage imageNamed:#"two.png"];
_tile3.image = [UIImage imageNamed:#"one.png"];
break;
...
}
}
arc4random_uniform is great for getting one random integer. When i need to get 2 or more random numbers, the outputs are not that great. What is the best way of doing this?
Sorry, but I don't believe you. You must be doing something other than what you've shown. The following code pasted into Playground consistently gives around a 20% match, not the 65-70% you claim:
import Cocoa
let sampleSize = 1000
var count = 0
for i in 1...sampleSize {
var randomNumber1 = arc4random_uniform(5)
var randomNumber2 = arc4random_uniform(5)
if randomNumber1 == randomNumber2 {
++count
}
}
println( Double(count) / Double(sampleSize) )
Whatever problem you're having, it isn't with how arc4random_uniform generates pairs of values.
Would using an array of numbers be a solution for you?
You can have a mutable array of numbers `[#0, #1, #2, #3, #4] and retrieve one number from a random index
NSMutableArray *array = [NSMutableArray arrayWithObjects:#0, #1, #2, #3, #4];
NSInteger firstIndex = arc4random_uniform([array count]);
NSNumber *firstNumber = array[index];
Remove the number you've just found:
[array removeObjectAtIndex:firstIndex];
And than repeat the same for the second number. The first retrieved number won't be in the array anymore so even if the arc4random_uniform() gives you the same value (your 65-70% case) the actual number you are gonna use in your switch case it's gonna be different.
This approach is probably a bit clumsy, but I think it does what you need giving you a bit of control over the randomness.

Using the objectAtIndex method in a switch block

I have an array of lattitudes and longitudes in my array,
NSArray *anArrayOfFloatObjects = [NSArray arrayWithObjects:
[NSNumber numberWithDouble:pinLocation1.latitude],
[NSNumber numberWithDouble:pinLocation1.longitude],
[NSNumber numberWithDouble:pinLocation2.latitude],
[NSNumber numberWithDouble:pinLocation2.longitude],
[NSNumber numberWithDouble:pinLocation3.latitude],
[NSNumber numberWithDouble:pinLocation3.longitude],
nil];
What I want to do is use a switch statement to go through the array (i.e. objectAtIndex..)
switch (self.anArrayOfFloatObjects objectAtIndex:) {
case :0
//switch the pin color to red
break;
case :2
//switch pin color to green
break;
default:
break;
}
This obviously doesnt work. Does anyone know any other way?
I believe what you are looking for is
[anArrayOfFloatObjects indexOfObject:number]
Maybe this code will help:
NSArray *anArrayOfFloatObjects; //Your array
for (NSNumber *number in anArrayOfFloatObjects) {
switch ([anArrayOfFloatObjects indexOfObject:number]) {
case :0
//switch the pin color to red
break;
case :2
//switch pin color to green
break;
default:
break;
}
}
EDIT:
Following #MikeS comment you can do something like this:
for (int index = 0; index < [anArrayOfFloatObjects count]; index++) {
switch (index) {
case :0
//switch the pin color to red
break;
case :2
//switch pin color to green
break;
default:
break;
}
}
Avoiding the need of calling [anArrayOfFloatObjects indexOfObject:number]
try fast enumeration
for(id item in anArrayOfFloatObjects){
NSLog(#"%#", item);
}
You can also look into NSArray's enumerateObjectsUsingBlock.
[yourArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"Index: %ld - Object: %#", idx, obj);
}];

Rotation With Animation in GPUImage

I Am using GPUImage.
I Want to Rotate (With 90, 180, 270, 360 degree) Image With Animation using GPUImageFilter.
Please Help.
Thanks in Advance.
Just Check What i did to do For Rotation
int tag - is defined in .h file
-(IBAction)btnRotate_Clicked:(id)sender
{
[self hideFilterView];
[self hideFontView];
[self hideEnhanceView];
if (tag == 0)
{
staticPictureOriginalOrientation = UIImageOrientationRight;
tag = 1;
}
else if (tag == 1)
{
staticPictureOriginalOrientation = UIImageOrientationDown;
tag = 2;
}
else if (tag == 2)
{
staticPictureOriginalOrientation = UIImageOrientationLeft;
tag = 3;
}
else
{
staticPictureOriginalOrientation = UIImageOrientationUp;
tag = 0;
}
UIImageOrientation orientation = staticPictureOriginalOrientation;
switch(orientation){
case UIImageOrientationUp:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatioAndFill];
break;
case UIImageOrientationLeft:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatio];
break;
case UIImageOrientationRight:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatio];
break;
case UIImageOrientationDown:
[self.MimageView setFillMode:kGPUImageFillModePreserveAspectRatioAndFill];
break;
default:
break;
}
[self prepareStaticFilter];
}
-(void) prepareStaticFilter
{
isImageProcessed = TRUE;
[staticPicture addTarget:filter];
if (hasBlur)
{
[filter addTarget:blurFilter];
[blurFilter addTarget:self.MimageView];
}
else
{
[filter addTarget:self.MimageView];
}
GPUImageRotationMode imageViewRotationMode = kGPUImageNoRotation;
switch (staticPictureOriginalOrientation)
{
case UIImageOrientationLeft:
imageViewRotationMode = kGPUImageRotateLeft;
break;
case UIImageOrientationRight:
imageViewRotationMode = kGPUImageRotateRight;
break;
case UIImageOrientationDown:
imageViewRotationMode = kGPUImageRotate180;
break;
default:
imageViewRotationMode = kGPUImageNoRotation;
break;
}
[filter setInputRotation:imageViewRotationMode atIndex:0];
[staticPicture processImage];
}

How to get the current active network type (wifi or 3G) of iPhone, without using the Reachability class

In my case, I can not use the Reachability class, because I am using iPhone in a wifi network which can not access the internet. It's just an intranet wifi.
That means, the Reachability class will return Not Reachable.
-(void)newtworkType {
NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:#"statusBar"] valueForKey:#"foregroundView"]subviews];
NSNumber *dataNetworkItemView = nil;
for (id subview in subviews) {
if([subview isKindOfClass:[NSClassFromString(#"UIStatusBarDataNetworkItemView") class]]) {
dataNetworkItemView = subview;
break;
}
}
switch ([[dataNetworkItemView valueForKey:#"dataNetworkType"]integerValue]) {
case 0:
NSLog(#"No wifi or cellular");
break;
case 1:
NSLog(#"2G");
break;
case 2:
NSLog(#"3G");
break;
case 3:
NSLog(#"4G");
break;
case 4:
NSLog(#"LTE");
break;
case 5:
NSLog(#"Wifi");
break;
default:
break;
}
}
For your intranet wifi I think you can also use Reachability
You only need to change the host name to your intranet host.
Such as :
struct sockaddr_in ip4addr;
int s;
ip4addr.sin_family = AF_INET;
ip4addr.sin_port = htons(80);
inet_pton(AF_INET, "192.168.0.1", &ip4addr.sin_addr);
s = socket(PF_INET, SOCK_STREAM, 0);
bind(s, (struct sockaddr*)&ip4addr, sizeof ip4addr);
Reachability * reach = [Reachability reachabilityWithAddress:&ip4addr];
above code is wrote by faildrop , https://github.com/tonymillion/Reachability/issues/6
I do not test , but I think it can deal with your problem

Calculator divide by zero

I created a simple calculator. Everything works great; however, if I divide by zero, I would like to show an error message. I know how to do alert popups, but I don't know how to implement it so it comes up when I divide by zero. Here is a snipped of my calculator code:
- (IBAction)buttonOperationPressed:(id)sender {
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
result = result / currentNumber;
break;
case 5:
currentOperation = 0;
break;
default:
break;
}
}
currentNumber = 0;
CalcDisplay.text = [NSString stringWithFormat:#"%g",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
userInTheMiddleOfEnteringDecimal = NO;
You can just add a test prior to doing the division e.g. change:
case 4:
result = result / currentNumber;
break;
to:
case 4:
if (currentNumber == 0)
// ... do alert here ...
else
result = result / currentNumber;
break;
You have to check if the second division operand is zero, and if yes, then print an error message. Don't forget, that you can't just compare double or something with ==, you have to use presicion, like this:
case 4:
if(ABS(currentNumber) < 1e-12) // most probably its zero
// your message
return;
- (IBAction)buttonOperationPressed:(id)sender {
if (currentOperation == 0) result = currentNumber;
else {
switch (currentOperation) {
case 1:
result = result + currentNumber;
break;
case 2:
result = result - currentNumber;
break;
case 3:
result = result * currentNumber;
break;
case 4:
if(currentNumber == 0){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}else{
result = result / currentNumber;
}
break;
case 5:
currentOperation = 0;
break;
default:
break;
}
}
currentNumber = 0;
CalcDisplay.text = [NSString stringWithFormat:#"%g",result];
if ([sender tag] == 0) result = 0;
currentOperation = [sender tag];
userInTheMiddleOfEnteringDecimal = NO;
Please try this code, I have copied an pasted the code you have given and added some necessary lines to it which i felt would solve your issue.

Resources