How to pass 2 parameters in Objective-C - ios

In iOS application development, how do I pass 2 parameters to login button?
I want to pass username and password on the button click of login button.
I have given in this manner:
-(IBAction)Login_Method:(id)sender withpassword:(id)password
{
}

It is not possible to send 2 parameters in an IBAction method.
What you can do is
Create 2 outlets and then connect these to password and username textfields.
On Clicking the login button, read the text value from the above 2 outlets.
Your login button action method will be like this
//username and password are UITextfields
-(IBAction)Login_Method:(id)sender
{
id name=[username text];
id pass=[password text];
}

As far as I know, IBActions are defined this way:
- (IBAction) actionMethod:(id)sender
Unless your button is subclassed much differently than usual, it is not going to call IBAction with an extra parameter (your withpassword: password).
You will have to use the standard definition above, get the call from the UIButton, and then get the text from your fields and then you can pass that to another method that will do the login with those two fields - unrelated to the UIButton's IBAction.

Typically, when you link a UIButton to a method in Interface Builder, that method will have no parameters. Technically, it can have zero, one, or two. The first is the sender (the button that was tapped) and the second is the event (the tap).
See the target-action mechanism for controls:
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
Also, you will typically link user inputs (such as UITextField instances) as IBOutlets. Then, you can access the user input through the text property:
// in your interface (header file):
IBOutlet UITextField *userNameTextField;
// in your implementation file:
NSString *userName = userNameTextField.text;
Finally, you should use correct types. Usernames and passwords are probably NSString* (pointers to NSString objects). "id" is the generic type and is not necessary here.

Related

What's the difference with :(id)sender?

What's the difference between declaring a UIButton in Xcode like this:
- (IBAction)testButton;
and declaring a button like this:
- (IBAction)testButton:(id)sender;
I understand that in the .m file you would then implement the buttons accordingly, as shown below:
- (IBAction)testButton
{
// insert code here..
}
and setting it up like this:
- (IBAction)testButton:(id)sender
{
// insert code here..
}
Is there any additional things you can do by declaring the button with :(id)sender, is there some additional stability, or is there no difference?
With :(id)sender you are able to access the button itself through the sender variable. This is handy in many situations. For example, you can have many buttons and give each a tag. Then use the [sender tag] method to find which button was tapped if many buttons are using this IBAction.
- (IBAction)someMethod:(id)sender {
// do stuff
}
Using (id)sender, you have a reference to who sent the method call. Please note, this doesn't have to be limited to a UIButton.
If you're created this method via control-dragging from the storyboard an only hooking up a single button, then sender is basically useless (it will always be the same), and should probably be marked as unused:
#pragma unused (sender)
(The compiler can better optimize your code if you do this.)
However, there's nothing wrong with hooking up several UI elements to the same IBAction method. You can then distinguish the sender via:
[sender tag]
...which returns an int that was either set via the storyboard or programmatically.
Moreover, you can call this method elsewhere in your class. You can either pass nil as the sender, or you can pass it a particular UI element in order to force it into the results you've coded for objects of that tag.
Nonetheless, if you plan to call the method with a nil argument, you can always throw:
if(!sender)
... into the method in order to handle special logic for when the method has been invoked programmatically as opposed to via user interaction.
It allows you to know which button you are working with. I have posted a simple example for a card game below
- (IBAction)flipCard:(id)sender {
[self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender]];
self.flipCount++;
[self updateUI];
}
This method is used for a card flipping game. There are multiple buttons on the screen representing different cards. When you hit the button, a card in the model must be flipped. We know which one by finding the index of the variable sender

Many UIButton in .xib with different tags

I have 17 button in my xib. And I have set them tag values 1 to 17.
Can somebody can tell me, how to connect all 17 buttons with a single variable name in .h and get a particular button in .m with it's tag value.
Thanks
I just tested this, and I know that if you select all your buttons in storyboards, and control drag them to the appropriate controller in an assistant editor you can create a collection of outlets representing all the buttons. The resulting code was:
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *buttons;
no its not possible as per my experience. IBOutlet i.e. Interface Builder Outlet always refers to a single connection between an interface component (like button) and a variable in interface (like IBOutlet UIButton *myButton). This one-to-one relation.
There needs to be an IBOutlet per button, so you'll need to create all 17 of them. Connect buttons to outlets individually, and then you will be able to put them into an array inside your initializer if you need them in an array.
You can save on the IBAction methods, though: make one method like this
-(IBAction)buttonClicked:(id)sender {
}
You can connect this method to all buttons, and look at the tag of the (id)sender to decide which button called your action.
You can't give a one reference to 17 button but you can assign one method to 17 buttons like #dasblinkenlight said
You have to just set the IBAction method to all button clicked event
and using tag value you can access the button which you want
-(IBAction)buttonClicked:(id)sender {
int j = [sender tag];
NSLog(#"Clicked Button %i", j);
}

Is it possible to convert description (String representation) of some object to an object of some class?

I need to pass a parameter to IBAction (but it has only sender(id) - UIButton in my case), so I'm wondering if it possible to convert description of some object to an object. Right now I'm passing parameter as button's [titleLabel text]:
[[button titleLabel]setText:[someObject description]];
And in IBAction I'm getting description:
- (IBAction)AddToCalendarEvent:(id)sender {
NSString * description = [[sender titleLabel]text];
NSLog(#"description is %#", desc);
}
And now I want to convert this description to an object. Is it possible?
UPD
I'm dynamically filling table view with cells. Each cell has four buttons and I want these buttons to keep some object as parameter to pass to IBAction.
I think the best solution for you, based on what I've read and currently understand about your problem, is to maintain an array (or some other appropriate data structure) of your buttons on your View Controller. Then, in your action method that each button calls when it is tapped, you can search your array of buttons for the sender of your action method. Then, once you've figured out which button has been tapped, you can use that to then find whatever data you're looking for in your data model. You should apply this solution to your situation and it will probably end up looking a bit different, but the basic idea is sound. You should avoid maintaining state in your view (in this case your buttons) and it looks like you're approaching that from your description of the problem.
You definitely don't won't to convert in this way.
A simple option is to set the tag of each UIButton to a unique integer, and store an array of the objects you need to look up:
- (IBAction)AddToCalendarEvent:(id)sender {
NSInteger senderTag = [sender tag];
NSLog(#"Sender index = %d", senderTag);
// Use this tag as an index to the array.
}
A more complicated route is to subclass UIButton (usually not recommended), to store the associated data with each UIButton. Then you can look it up, once again from the sender.

UITextField not updating

I'm having trouble updating the UITextField for an iPhone app. I've set the layout with the Interface Builder, created an instance of the text field in the ViewController, and set the ViewController as the delegate for the text field.
The text field object in code doesn't seem to be responding when I enter in information and press Done.
Does anyone have any ideas why its not working?
If you are creating the text field in interface builder, you don't need to also alloc and init it in code. Link the text field to files owner in IB (I'm assuming files owner is your view controller) as the delegate. If you need to refer to it specifically, also create and outlet in your view controller and link that to your text field. This is covered in the most basic tutorial apps in the docs.
To respond when the done button is pressed, implement the textFieldShouldReturn method from the UITextFieldDelegate protocol. Resign first responder in that method and return YES.
Is your text field connected to the IBOutlet in your code? Maybe if you post some related code it would be helpful.

Getting the Value of a UITextField as keystrokes are entered?

Let's say I have the following code:
IBOutlet UITextField* nameTextField;
IBOutlet UILabel* greetingLabel;
I'd like the greetingLabel to read "Hello [nameTextField]" as soon as the user presses any key.
What I need basically is the iPhone equivalent of the Cocoa delegate method controlTextDidChange.
The textField:shouldChangeCharactersInRange: delegate method is called each time a keystroke occurs:
- (BOOL) textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
The string argument returns the character that is pressed. The actual textField's value (nameTextField.text) remains blank however.
What am I missing here? (I'd like nameTextField to reflect the exact string that the user has entered so far).
It turns out, the easiest way to do this is using Interface Builder:
Add a IBAction (to the ViewController, say, as in this case)
Ctrl-Click (or right click) on the UITextField in Interface Builder
Connect the "Editing Changed" event to the File's Owner's IBAction added in the first step.
Works like a charm :) (I can't believe I spent numerous days on this, and to realize now that the solution was much simpler than I'd thought :P)
you could register an action for the event UIControlEventEditingChanges on the text field:
[nameTextField addTarget:self action:#selector(updateLabelUsingContentsOfTextField:) forControlEvents:UIControlEventEditingChanged];
...
// TODO: error checking
- (void)updateLabelUsingContentsOfTextField:(id)sender {
greetingLabel.text = [NSString stringWithFormat:#"Hello %#", ((UITextField *)sender).text];
}
UITextField has a notification UITextFieldTextDidChange which will be fired every time the text changes if you register for it. Just register for that notification and in the method called by the notification, change the label's text.
To add to this, the object passed to your notification handler will have the text of the UITextField.
Hope that helps.

Resources