Error Objective C forControlEvents - objective-c

I am new to objective C and am having a problem with the following line. The error is: "Passing argument 3 of 'addTarget;action:forControlEvents:' makes integer from pointer without a cast." The wierd thing is that I get the warnings and everything works fine on the IPAD but on the simulator it works sometimes and other times it does not work. I have a textfield in a tableviewcell, when the user types it sends what they typed to a variable.
[textField addTarget:self action:#selector(setFilterCriteria:) forControlEvents:UITextFieldTextDidChangeNotification];
Here is the IBAction:
- (IBAction)setFilterCriteria:(id)sender {
UITextField *senderTextField = (UITextField *)sender;
appDelegate.setFilterCriteria = senderTextField.text;
}

You're specifying the wrong kind of thing for the control event.
UITextFieldTextDidChangeNotification is a notification name, not a control event type. You want one of the UIControlEvent... constants, like UIControlEventValueChanged.
(You're seeing the warning because the notification names are NSString*s, and the expected type of that argument is a defined numeric constant.)

Related

How does (id)sender work in cocos2d?

The following code works good for me:
In the init method of a menu layer:
CCMenuItemFont *item1 = [CCMenuItemFont itemWithString:#"Level 1" target: self selector: #selector(startLevel:)];
item1.userData = (__bridge void*) ([NSNumber numberWithInt:1]);
...//create menu and add in the item1
-(void)startLevel: (CCMenuItem *)sender
{
NSNumber *number = sender.userData;
...
}
My questions are:
I didn't pass item1 when call the method startLevel: how does it know that the sender is item1?
is it written into selector? or is it written in cocoa?
CCMenuItem passes itself as parameter to this selector. Details are in CCMenuItem source code.
Regarding omitting passing itself as a parameter, do you mean like...
- (void) pushedStart : (id) sender
{
//start game
}
but you can't do
[self pushedStart];
because it needs a parameter? If so, what you can do this:
id junkID;
[self pushedStart: junkID];
JunkID will initialize to whatever the hell it is an unassigned ID assigns to, so you pass it as a reference and just don't use it for anything, which is good if you want to have a "start game" button but have the game automatically start inside of a timer or whatever else you're doing with your buttons
As a side note, and getting more into the guts of cocoa, the way it KNOWS (and what YOU must not forget) is that colon. When you call a function you put the variable after a colon [self eat: food];
When you put together the menu item you set it up with target:self, which makes the button use itself (not the layer "self" you use when you call [self eatABanana]) as a target. The button push of
menuButton = target:self selector:#selector(pushButton:)
is represented like
[self pushButton:menuButton]
If you forgot that colon, it's the same as calling a function and not passing the variable, which doesn't give a very helpful error message insofar as it doesn't help you locate where the problem is occurring. I've spent hours upon hours chasing down memory crashes resulting from writing #selector(startGame) instead of #selector(startGame:) in those damn menu buttons. I always feel stupid when I finally figure it out.

Trouble while adding column - Cocoa

just a simple problem (I hope !)
I've got a void method which add a column to a table.
Why if I call that method programmatically (ex: [self method] ) my table won't update and instead if i call it through an IBAction (pushing a button from app) it works ?
Actually i can see from the log that the method is called in both cases but update data just with IBAction.
the method:
- (IBAction)void {
NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:#"1"];
[column setWidth:50];
[tableData addTableColumn:column];
[tableData reloadData];
[[column headerCell] setStringValue:#"aColumn"];
NSLog(#"Method called"); //The method is called in both cases
}
I can't find out what I am doing wrong.
(New to cocoa programming)
Thanks a lot !
Where did you call this programmatically? You might have called it before the view was loaded in an init method instead of something else like awakeFromNib.
I tried your code and got different results. It was called fine from code (and the table updated), but not from the button (and the log wasn't run either when attempting to call from the button).
The problem is the method name -- you shouldn't name a method void. Do you not get the error message in the console: "Could not connect the action void: to target of class AppDelegate"
The compiler won't even allow me to connect that method to the button (it looks like I can in IB, but I get that error message, and if I put the method in the .h file, it has no circle next to it that shows whether it's connected or not).

Why can I not reset a text field within an IBAction associated with it?

I have an IBAction called keyboardResponse associated with a text field called myTextFieldIBOutlet via the "Editting Changed" event handler in the xib:
- (IBAction)keyboardResponse:(id)sender
{
// process this single character - function I wrote else where that works fine.
[self processSingleCharacter:myTextFieldIBOutlet.text];
// clear input text
myTextFieldIBOutlet.text = #"";
}
It's supposed to clear the input after the user types something into it.
I get a run time error with this code in iOS Simulator:
Thread 1: EXC_BAD_ACCESS (code=2, address=0xbf7fff0c)
Why? I had synthesized the IBOutlet myTextFieldIBOutlet already.
if myTextFieldIBOutlet is synthesized, you should change the last line to:
self.myTextFieldIBOutlet.text = #"";
If the textfield you want to clear is the same control that calls this action, you can also use the sender variable you are sending
[sender setText:#""];

How to stop warning for UIView may not respond to selector

I have a class that has a UIView as a property. Sometimes I pass in a UILabel; sometimes a UITextField. No matter which I pass in, I want the class to set the text. Currently I am doing this, which works:
if ([self.viewToUpdate respondsToSelector:#selector(setText:)] && !self.newAnswer)
[self.viewToUpdate setText:[[self.choices objectAtIndex:indexPath.row] text]];
The problem is, this gives a warning, because even though I'm checking respondsToSelector, Xcode doesn't know that my UIView will respond to setText:. How can I remove this warning?
I know that I can specifically check to see if it's a TextField or a Label, and then cast to a TextField or a Label, respectively, but this would be a pain, and if I ever have more types of views, I'd have to add a few more lines of code for each one.
I thought about creating my own protocol, and then having my class have id as the type for viewToUpdate... but of course UITextField and UILabel wouldn't conform to that protocol...
try just casting it as an id:
if ([self.viewToUpdate respondsToSelector:#selector(setText:)] && !self.newAnswer)
[(id)self.viewToUpdate setText:[[self.choices objectAtIndex:indexPath.row] text]];

Subclassing and Casting in Objective C

I came across a strange problem today. I created a subclass of UIView and added only 1 method to the template code provided by xcode.
#interface FloatView : UIView {
}
- (void)floatTest:(CGFloat)x;
#end
- (void)floatTest:(CGFloat)x {
NSLog(#"float was %f", x);
}
Then in my appDelegate I had code like this:
UIView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];
Pretty simple, right? What should this print out? I thought it would something like "10.0000", but no, it prints out "0.000000".
I wrestled with this for hours, trying to figure out what I was doing wrong, and then I changed the code in my appDelegate to
FloatView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];
Only then, did it print out the expected "10.0000". Why is this so? I've declared FloatView as a subclass of UIView, shouldn't I be able to assign a FloatView object to a UIView pointer without problems?
Even though floatView was declared a pointer to a UIView, it's really a floatView and it should be able to handle the floatTest message? Am I totally off base here?
Actually, polymorphism is working as expected. If it didn't work, nothing would have been printed (in your example, 0.0000 is being printed). The thing is, while your instance actually responds to testFloat:10.0f message, since the compiler can't statically see the method declaration (as UIView class doesn't declare such a method), it assumes that your method takes ... as argument and returns id.
When CGFloat is passed to a method that expects variable number of arguments (...), it's promoted to double. Thus, the receiving method is passed a double argument and thinks it's a float and it doesn't get printed correctly.
You can verify this behavior by changing NSLog line to:
NSLog(#"%f", *(double*)&x);
When the compiler sends the message to FloatView* rather than a UIView*, it can find the exact signature of the method. It can see it really expects CGFloat and doesn't promote the argument to double. As a result, it works correctly.
Additionally, if UIView* contained the method declaration that took a CGFloat, the compiler would call the method appropriately. To summarize, this is not a polymorphism issue; it's a missing method signature issue.