How Do I Implement If-Statement within Method? - iphone

Im a noob to iphone development and I am having trouble implementing an if-statement within the didSelectIndex method of AwesomeMenu. The method fires and returns the value of the index selected, but it doesn't respond when I attempt to use the index in a conditional statement within the method. For example, my log only prints "Select the index : 0", but not "Index 0". This is very frustrating to say the least. Any help is greatly appreciated.
MY CODE:
- (void)AwesomeMenu:(AwesomeMenu *)menu didSelectIndex:(NSInteger)idx{
if (idx==0) {
NSLog(#"Index 0"); //Doesn't print
}else if(idx==1){
NSLog(#"Index 1"); //Doesn't print
}else{
NSLog(#"Else Block test"); //Doesn't print
}
NSLog(#"Select the index : %d",idx); //<--This Works.
}

The delegate is simply set incorrectly.
The boilerplate code for Awesome Menu includes the NSLog statement that is being called. Your above code is fine. You are simply not setting the delegate for the menu to the appropriate object. As a result, your above code never runs.
If you need assistance in this matter, please post the code demonstrating how you initialize your AwesomeMenu.
In any case, search your entire project for the phrase "Select the index" and you will find the delegate method that is actually being executed instead of your current code.

There is no problem with your If - else statement. check your (NSInteger)idx closely.
Its working fine
[self AwesomeMenu:nil didSelectIndex:1];
- (void)AwesomeMenu:(id )menu didSelectIndex:(NSInteger)idx{
if (idx==0) {
NSLog(#"Index 0"); //Doesn't work
}else if(idx==1){
NSLog(#"Index 1"); //Doesn't work
}
NSLog(#"Select the index : %d",idx); //<--This Works.
}
Output
Index 1
Select the index : 1

You can try:
NSInteger i = 2;
NSInteger j = 2;
if (i == j) {
NSLog(#"equal")
}

Related

Assertion Failure in Calculator Program

So I'm working on a simple calculator program to get used to cocoa and objective C. I've redone the whole thing multiple times and every time I finish coding, the first time i build it, it works fine, but every time after that the window wont launch and it gives me these errors:
2013-01-11 10:32:14.760 Visual Caluclator Fix[39892:403] *** Assertion failure in -[NSTextFieldCell _objectValue:forString:errorDescription:], /SourceCache/AppKit/AppKit-1138.47/AppKit.subproj/NSCell.m:1564
2013-01-11 10:32:14.762 Visual Caluclator Fix[39892:403] Ignoring exception raised in __-[NSPersistentUIManager restoreAllPersistentStateWithTalagentWindows:registeringAsReadyWhenDone:completionHandler:]_block_invoke_3: Invalid parameter not satisfying: aString != nil
I've concluded that the problem lies in my textEdited method, because when I comment the code inside of it out, the program has no issues running; however, I have no idea why this is, or why it would run the first time and not any subsequent times. When I put in an exception breakpoint, it points me to the one line in the updateUI method and the call to [self updateUI] in the textEdited method. The following code is the textEdited method and the other methods it references.(I'm fairly sure there's nothing wrong with the solve method because I used it in a command prompt calculator and it worked great. Also, I know this is a pretty convoluted way to program a calculator, with the strings and everything, but I was just trying to integrate the code I already had for the command prompt program into a cocoa program.)
In the AppDelegate class:
- (void)updateUI{
[self.calculationView setStringValue: self.calculation.calcString];//Exception breakpoint points here
}
- (IBAction)textEdited:(id)sender {
self.calculation.calcString = self.calculationView.stringValue;
[self.calculation solve];
[self updateUI];//Exception breakpoint points here
}
In the Calculation class:
- (NSString*)solve{
for (int i = 0; i < [self.calcString length]; i++) {
NSRange nextChar = NSMakeRange(i, 1);
if ([[self.calcString substringWithRange: nextChar] isEqualToString: #"*"]||
[[self.calcString substringWithRange: nextChar] isEqualToString: #"/"])
[self calcTerm: i];
}
for (int i = 0; i < [self.calcString length]; i++) {
NSRange nextChar = NSMakeRange(i, 1);
if ([[self.calcString substringWithRange: nextChar] isEqualToString: #"+"]||
[[self.calcString substringWithRange: nextChar] isEqualToString: #"-"])
[self calcTerm: i];
}
return self.calcString;
}
This might help with your problem:
http://www.raywenderlich.com/10505/my-app-crashed-now-what-part-2
The site explains how assertion errors work and demonstrate how you would fix an error like that.
It sounds to me like something in calcTerm: is setting calcString to nil. Thus, when you retrieve it later to set the field's string value to it, you end up setting the field's string value to nil, which it doesn't like.
You can check this by logging the value of calcString just before the end of solve. Then, start stringing up log statements and/or breakpoints in calcTerm: to find out how you're swapping out your string for nil.

UITextField strange behaviour for blank checking

I've a UITextField say txtTitle. I want to check for not blank of that field at the time of inserting data into database.
For that I written
if(![txtTitle.text isEqualToString:#""])
{
//Save
}
But where I am shocked is its not working! I did these type of checking before and its working properly. But not with this case. So that I checking it using following,
if(txtTitle.text!=NULL)
{
//Save
}
It's working properly.
Now here I am confusing about this. I used to print NSLog(#"%#",txtTitle.text) without inputting anything into it. Its printed (null).
Someone please justify the difference between two IF conditions.
Thanks
Maybe you can check for the length property of the string instead, using
if([txtTitle.text length] > 0){
// Save
}
I think the difference is between a completely uninitialized string and a string that has been initialized, but is simply empty.
Hope this helps
#Hemang
As you have mentioned that NSLog gives you (null)..you have to compare like
[txtTitle.text isEqualToString:#"(null)"]
other wise use
if([txtTitle.text length] > 0)
{
}

Problem with stringByEvaluatingJavaScriptFromString

I wanna to know abt "stringByEvaluatingJavaScriptFromString".
According to the apple doc.
"The result of running script or nil if it fails."
I have a method in which inside a for loop i'm passing a string value to stringByEvaluatingJavaScriptFromString. what will it do ?? will this get response for every string or something else will happen??
I was doing like this...
- (void)loadWithStartPoint:(NSString *)startPoint endPoint:(NSMutableArray *)endPoints options:(UICGDirectionsOptions *)options {
for (int idx = 0; idx < [endPoints count]; idx ++)
{
NSString *msg = [NSString stringWithFormat:#"loadDirections('%#', '%#', %#)", startPoint, [endPoints objectAtIndex:idx], [options JSONRepresentation]];
[googleMapsAPI stringByEvaluatingJavaScriptFromString:msg];
}
}
Inorder to get response to every string what should I do? I think that it should get response to every string that i'm passing here. Please tell me what m doing wrong and how would i manipulate my code to get response to all strings that m passing.
Any help would be appreciated .Thnx in advance.
You should make your javascript method to return a default string or something if even an error occurs in the script.
function loadDirections()
{
try
{
//Your code goes here which returns some result
}
catch(err)
{
var errorFlag = "ERROR";
return errorFlag;
}
}
and then you should alter your Objective C code like below
NSString *msg = [NSString stringWithFormat:#"loadDirections('%#', '%#', %#)", startPoint, [endPoints objectAtIndex:idx], [options JSONRepresentation]];
if([msg isEqualToString:#"ERROR")
{
//Do some error handling
}
else
{
//Your actual code goes here
}
Update for the comment:
To solve your javascript asynchronous problem either (1) you can change your design and call the javascript method only after getting response from the first call (2) or else you can use NSTimer which will will give a little time for the execution. In my opinion changing your design as per the first option would be perfect.
Have a look at these questions
stringByEvaluatingJavaScriptFromString doesn't always seem to work
return value javascript UIWebView

Pass a block of code?

Is it possible to pass a block of code, for example:
int i = 0;
while (i < [array count]) {
//Code to pass in here
i++;
}
Reason being that i need to perform various actions on every item in an array at different times, it'd be nice to have 1 method and pass it a block of code to run.
Have you considered using blocks. It's just an idea and not working or compilable code
typedef int (^block_t)();
-(void) methodName:(block_t) code_block
{
int i = 0;
while (i < [array count]) {
code_block() //Code to pass in here
i++;
}
block_t youCode = ^{ NSLog("Just an example"); }
[self methodName:youCode];
You can definitely iterate an array and process a block of code on it. This feature has been a standard part of Objective C since 2.0, iOS since 4.0 and in addition was included in Snow Leopard. If you look up the NSArray class reference you will find the following functions:
enumerateObjectsAtIndexes:options:usingBlock:
Executes a given block using the
objects in the array at the specified
indexes.
enumerateObjectsUsingBlock: Executes a
given block using each object in the
array, starting with the first object
and continuing through the array to
the last object.
enumerateObjectsWithOptions:usingBlock:
Executes a given block using each
object in the array.
You can define the code block to be executed globally in your implementation file, or in place where its needed. You can find some good examples on block programming here: http://thirdcog.eu/pwcblocks/.
It sounds like you want "blocks", which are a feature of Objective-C similar to "lambdas", "anonymous functions" and "closures" in other languages.
See Apple's documentation: Blocks Programming Topics
You should put the code into a method and call the method like so:
-(void)foo{
int i = 0;
while (i < [array count]) {
[self myMethod];
i++;
}
}
-(void)myMethod{
//Code to pass in here
}
You could also store the method as a variable allowing you to change which method is called
SEL methodToCall = #selector(myMethod);
-(void)foo{
int i = 0;
while (i < [array count]){
[self performSelector:methodToCall];
i++;
}
}
-(void)myMethod{
//Code to pass in here
}
first of all you could give a more detailed example.
second you could take a look at Action or Func in case you need a return message (well something equivalent for obj-C if exists)
but again, not understanding what you need to do, it is hard to give you an answer
cause from you Q i could understand as #Trevor did that you need to run a method:
int i = 0;
while (i < [array count]) {
if (i % 2)
EvenMethod(array[i])
else
OddMethod(array[i])
i++;
}
If you can live with 4.0+ compatibility, I highly recommend the use of blocks.
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
gives you all you need and you can define your block right where you need it. There are some other variants of this, too. Please refer to the 'NSArray' documentation.
Why not just define functions that do what you want, and call them at various times with the items in your array as arguments?
If your concern is that you don't want redundant code with multiple while loops you have here, you could write a function that takes an array and a function as an argument, then applies that function to every element in the array.
Adapted from here:
//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer
// <pt2Func> is a pointer to a function which returns void and takes an NSObject*
void DoForAllItems( NSArray* array, void (*pt2Func)(NSObject*) )
{
int i = 0;
while (i < [array count]) {
(*pt2Func)([array objectAtIndex:i]);
i++;
}
}
// 'DoIt' takes an NSObject*
void DoIt (NSObject* object){ NSLog(#"DoIt"); }
// execute example code
void Pass_A_Function_Pointer()
{
NSArray* array= [NSArray arrayWithObjects:#"1", #"2", nil];
DoForAllItems(array, &DoIt);
}
http://thirdcog.eu/pwcblocks/#objcblocks
Blocks were added recently to Objective-C I hope they have found their way to the Iphone also.
and it was anwered here also before:
Using Objective-C Blocks
Regards
If you are using Objective C++, I would strongly recommend function objects (even over blocks). They have a nice syntax, are easy to use, and are supported everywhere on modern C++ compilers (MSVC++11, GNUC++11, and LLVMC++11):
void go( function<void (int arg)> func )
{
int i = 0;
while (i < [array count]) {
//Code to pass in here
func( i ) ; // runs func on i
i++;
}
}
calling it:
go( []( int arg ){ // the square brackets are the "capture"
printf( "arg was %d\n", arg ) ; // arg takes on whatever value was passed to it,
// just like a normal C function
} ) ;

Building a simple guessing game, iPhone

I'm trying to build a simple guessing game. I'm having a weird problem:
-(int)setRandom {
randomNum=(int)arc4random() % 100;
return randomNum;
}
-(IBAction)submit
{
num=[self setRandom];
if([numberField.text intValue] > num)
randomNumLabel.text=#"Too high. Try again";
else if([numberField.text intValue] < num)
randomNumLabel.text=#"Too low. Try again";
else
randomNumLabel.text=#"You got it, congrats!";
}
The problem is that I get a new random number every time I press submit. I thought that the first method would create the random number, and it would be the same every time, but apparently not. How do I fix this?
Don't call setRandom every time in submit. arc4random() returns a new random number every time you call it.
Create a property to store the random number and set it only when you need to -- in init and when the game resets.
For this purpose you need a global variable.so first a fall declare
NSInteger num; in .h class then in viewDidLoad write like this
- (void)viewDidLoad {
num=[self setRandom];
//you stuff
}
then in submit
-(IBAction)submit
{
if([numberField.text intValue] > num)
randomNumLabel.text=#"Too high. Try again";
else if([numberField.text intValue] < num)
randomNumLabel.text=#"Too low. Try again";
else
{
randomNumLabel.text=#"You got it, congrats!";
num=[self setRandom];
}
}
-(int)setRandom {
randomNum=(int)arc4random() % 100;
return randomNum;
}
Here you get a random number at view load then you get new random number when your answer matches with the number.
So this will help you.