Calling function in xcode iPhone - iphone

If I have this function for button click
-(IBAction)loginButton:(UIButton *)sender{ }
How can I call this button function from this another method
-(void)increaseAmount {
myNumber = myNumber+0.01;
if (myNumber >= 1) {
[self loginButton:sender];
}
progressViewAuto.progress = myNumber;}
I have tried the above code but getting error that USE OF UNDECLARED IDENTIFIER 'sender'

Simply pass in nil or even self.

And, if you want to be perfectly correct, you can link your UIButton to IBOutlet UIButton* theLoginButton; and then say [self loginButton:theLoginButton];.
But this would only be needed if you actually reference the sender in your loginButton routine, and that's the exception rather than the rule.

You probably just want to send nil, like this:
[self loginButton:nil];

Related

sender currentTitle not recognized in Xcode

I am doing something as simple as get the current title of an UIButton
-(IBAction)buttonPressed:(id)sender{
NSString *someString = [sender currentTitle];
}
For some reason Xcode confuses sender with self because the complete options only retunrns methods that belongs to "self". No matter whatever I do, I get the same
-(IBAction)buttonPressed:(id)sender{
UIButton *btn = (UIButton *)sender;
NSString *someString = [btn currentTitle];
}
Xcode crashes in NSString line with "unrecognized selector sent to btn". I can copy working code from another project and the same happens. What could be wrong?
SOLUTION
Resarted XCode and it worked fine o.O
I don't think Xcode is confusing sender with self, what's happening is that Xcode knows nothing about sender, since it was declared as id, which means Xcode only knows it's an object.
The suggestions you are getting in Xcode are probably just methods every object has.
You have to make sure that sender is what you expect, try doing this and checking if it's actually a button or something else:
-(IBAction)buttonPressed:(id)sender{
NSLog(#"Sender: %#", sender);
}
SOLUTION
Resarted XCode and it worked fine o.O
Possible reason for "unrecognized selector sent to btn" is when you call a method which was not actually written. Or you might be called
[self buttonPressed];
instead of
[self buttonPressed:];
Your problem is your calling the 'id' not the button its self. Replace the 'id' with 'UIButton' like so...
-(IBAction)buttonPressed:(UIButton *)sender{
NSString *someString = sender.currentTitle;
}
I think the problem is wrong syntax
It is
sender.currentTitle;
OR
btn.currentTitle;
currentTitle is a property and there is no function called currentTitle and hence you get the error "unrecognized selector sent to btn".

Calling Button-Clicked Function From Code

I have a function set up in my code like so:
-(IBAction) buttonClicked: (id) sender{
//various expressions here
}
The question is, how can I call this buttonClicked() function from somewhere else in the code, without requiring a user click the button. For example, how can I call it from viewDidLoad()?
Thank you for any help.
If you're calling in the same file, you can use:
[self buttonClicked:self];
Depending on what your method does.

pass a variable between two methods

I was trying to pass a variable of type NSString from a method to another. what I have done is:
-(void)some{
NSString *lat = something
NSString *longt = somethingElse
[self test:lat:longt];
}
and then
- (IBAction)test:(NSString *)lat:(NSString *)longt{
doSomeThing
}
But my problem is that now the IBAction button is activated without my press.
how do I run the method IBAction under my control
you cannot pass arbitrary parameters through an IBAction, you can either pass the control sending the action or nothing:
-(IBAction)action:(id)sender;
or
-(IBAction)action;
The test method should not be an IBAction. Instead do this:
- (void)test:(NSString *)lat:(NSString *)longt{
//doSomeThing
}
-(IBAction)myAction:(id)sender
{
//call test from here
[self some];
}
You should use void as returm type of method not ibaction. If u need it for some action thn call it from there.
use
- (void) test:(NSString *)lat:(NSString *)longt
instead of
- (IBAction)test:(NSString *)lat:(NSString *)longt

How to add (id) sender to the following -(IBAction)?

How do you add a (id) sender to the following code?
- (IBAction) gobutton: (UIButton *) button5 {
Everything I try fails, any help would be appreciated. Thanks.
EDIT: I need to keep the (UIButton *) button 5 reference in the (IBAction)
If I recall correctly, and if you are using this in the way I think you are,
- (IBAction) gobutton: (id) sender {
if(sender == button5)
//do something...
else
//do something else...
}
Assuming that you specified button5 as a parameter to indicate that this executes in response to button5 being pressed.
Ok, first.... IBAction doesn't really mean anything special except to Interface Builder. Basically:
#define IBAction void
So whenever you see IBAction, think "void". The only reason it's there is as a flag to tell Interface Builder that a method is a valid method to connect control actions to. The Objective-C compiler doesn't need to know about it and so it's defined to void since all "action" methods return void.
Second, action methods also have one argument which could be an object of any number of types. Because of this, action methods are supposed to use type id as the type for their argument. That way they can be passed a pointer to any Objective-C object without causing the compiler to generate a type checking error.
So usually actions should work something like this:
- (IBAction)myAction:(id)sender {
if (sender == self.someButton) {
UIButton *button = (UIButton *)sender;
...
return;
} else if (sender == self.someControl) {
UIControl *control = (UIControl *)sender;
...
return;
}
}
In other words, an id is almost like an untyped pointer like a void * is routinely used in C when some function needs to take a pointer to something of unknown type. sender could be different types of control, so something generic like id is used then sender is cast to something more specific once the code knows what it is.
Anyway, there is absolutely no reason to define something as having a return type of IBAction unless you are going to use that method as a target action in Interface Builder. Having an IBAction in your app delegate seems kind of unusual....
It's not clear what you are trying to do but most actions look like:
- (IBAction) gobutton: (id)sender;
The first parameter to an action is always the sender (you can specify the type and name as appropriate).
If a method is the action for a button, then the first parameter will be the button. If that method is the action for several buttons, then the first parameter will allow you to determine which button was tapped (as Leper describes).
What problem are you actually trying to solve?
There are techniques for passing information to the action method. For example, if you have a button that appears on a table view cell and performs the same action for every cell, then in the action method, you would want to be able to determine which cell's button was tapped.
How can I get the id of the sender before the user touches the control?
Found it! Set a tag and the use viewWithTag.
Can you create a simple structure that contains both the UIButton and the sender and use that?
struct myObject
{
UIButton* button5;
id sender;
}
...or, you could create your own NSObject (probably more cocoa-y):
#instance myObject : NSObject
{
...
}

How can I pass a parameter to this function?

I have the following code:
[replyAllBtn addTarget:self.target action:#selector(ReplyAll:) forControlEvents:UIControlEventTouchUpInside];
- (void)replyAll:(NSInteger)tid {
// some code
}
How can I send a parameter to the ReplyAll function?
The replyAll method should accept (id)sender. If a UIButton fired the event, then that same UIButton will be passed as the sender. UIButton has a property "tag" that you can attach your own custom data to (much like .net winforms).
So you'd hook up your event with:
[replyAllBtn addTarget:self.target action:#selector(ReplyAll:) forControlEvents:UIControlEventTouchUpInside];
replyAllBtn.tag=15;
then handle it with:
(void) ReplyAll:(id)sender{
NSInteger *tid = ((UIControl*)sender).tag;
//...
A selector function will normally be defined as such:
- (void) ReplyAll:(id)sender;
So the only parameter an action will ever receives is the actual control that called it.
You could just add a property to your control that can be read in replyAll
If you want to send an int value, set the tag of the button = the int value you want to pass. Then you can access the tag value of the button to get the int you wanted.
NSInteger is not a pointer. Try this
NSInteger tid = sender.tag;
It's working now :D.
{
NSInteger tid = [sender tag];
}
The MVC model used in Cocoa works differently. Basically, the idea is that a control (=view) such as a button only lets a function know it was pressed, not knowing what this means. The function then has to know all the dynamics and dependencies. In your case, it's the function that has to find the parameter. To accomplish that, you'll "bind" other objects to the function (= controller).
I suggest you read a few Cocoa tutorials first if you want to get ahead with iPhone programming.
There's a few good ways to do this. The two most commonly implemented would be to have the controller (who's receiving the action) know about possible senders, or having the sender itself have a method that you end up using to determine the proper behavior.
The first (my preferable way, but it's easy to argue the opposite) would be implemented like such:
#interface Controller : NSObject {
UIButton *_replyToSender;
UIButton *_replyToAll;
}
- (void)buttonClicked:(id)sender;
#end
#implementation Controller
- (void)buttonClicked:(id)sender {
if (sender == _replyToSender) {
// reply to sender...
} else if (sender == _replyToAll) {
// reply to all...
}
}
#end
The second way would be implemented in a manner such as:
typedef enum {
ReplyButtonTypeSender = 1,
ReplyButtonTypeAll,
} ReplyButtonType;
#interface Controller : NSObject {
}
- (void)buttonClicked:(id)sender;
#end
#interface MyButton : UIButton {
}
- (ReplyButtonType)typeOfReply;
#end
#implementation Controller
- (void)buttonClicked:(id)sender {
// You aren't actually assured that sender is a MyButton, so the safest thing
// to do here is to check that it is one.
if ([sender isKindOfClass:[MyButton class]]) {
switch ([sender typeOfReply]) {
case ReplyButtonTypeSender:
// reply to sender...
break;
case ReplyButtonTypeAll:
// reply to all...
break;
}
}
}
#end