I'm making a little demo app and I'm having trouble changing.
Heres the thing:
I have a UIButton that every click will add a character in a NSString in a UITextField.
And I put an IBAction(Mudar_Resposta) on that UITextField(campo) in the part 'Value Changed'.
In that IBAction, I put that:
- (IBAction)MudarResposta:(id)sender {
campo.text=#"lol";
}
But I can't get it to work. Any ideas?
Thanks.
The proper way to get it to work is to connect an action method to the Touch Up Inside event for your button. Within that method, edit they text for your text field.
- (IBAction)mudarResponsta:(id)sender { // Connect to Touch Up Inside of your button
campo.text = [NSString stringWithFormat:%# %#", campo.text, #"lol"]; // Add string ' lol' every time it's called
}
Connecting to Value Changed will never invoke the method because the value is never being changed—you're connecting the changing method to the change…if that makes any sense.
Most likely you didn't connect that action to anything in the XIB file.
- (IBAction)Button:(id)sender {
[self.contacts addObject:_txtField.text];
_txtField.text=#"";
}
Here contacts is an Array name which is a Mutable Array. txtField is UITextField.
Related
I have a text field and I bind it to an NSString instance variable.
When I type in the text field, it does not update the variable. It waits until I press the Enter key. I don't want to hit Enter every time.
What do I need to change in order to make the binding change value immediately?
By default, the value binding of an NSTextField does not update continuously. To fix this, you need, after selecting your text field, to check the "Continuously Updates Value" box in the Bindings Inspector under the Value heading:
However, most often, what you really want to do is update the property to which the text field is bound when the user has finished editing and presses a button ("Save" or "OK", for example). To do this, you needn't continuously update the property as described above, you just need to end editing. Daniel Jalkut provides an extremely useful implementation of just such a method:
#interface NSWindow (Editing)
- (void)endEditing;
#end
#implementation NSWindow (Editing)
- (void)endEditing
{
// Save the current first responder, respecting the fact
// that it might conceptually be the delegate of the
// field editor that is "first responder."
id oldFirstResponder = [oMainDocumentWindow firstResponder];
if ((oldFirstResponder != nil) &&
[oldFirstResponder isKindOfClass:[NSTextView class]] &&
[(NSTextView*)oldFirstResponder isFieldEditor])
{
// A field editor's delegate is the view we're editing
oldFirstResponder = [oldFirstResponder delegate];
if ([oldFirstResponder isKindOfClass:[NSResponder class]] == NO)
{
// Eh ... we'd better back off if
// this thing isn't a responder at all
oldFirstResponder = nil;
}
}
// Gracefully end all editing in our window (from Erik Buck).
// This will cause the user's changes to be committed.
if([oMainDocumentWindow makeFirstResponder:oMainDocumentWindow])
{
// All editing is now ended and delegate messages sent etc.
}
else
{
// For some reason the text object being edited will
// not resign first responder status so force an
/// end to editing anyway
[oMainDocumentWindow endEditingFor:nil];
}
// If we had a first responder before, restore it
if (oldFirstResponder != nil)
{
[oMainDocumentWindow makeFirstResponder:oldFirstResponder];
}
}
#end
So if for example you had a "Save" button targeting your view controller's method -save:, you would call
- (IBAction)save:(id)sender
{
[[[self view] window] endEditing];
//at this point, all properties bound to text fields have the same
//value as the contents of the text fields.
//save stuff...
}
The previous answer is beautiful, and I learned from it about tricking the Window/View/Document system to end-editing on everything at the programmer's will.
However, the default responder chain behavior (including the preservation of the first responder until the USER moved their focus to something else) is fundamental to the Mac's "look and feel" and I wouldn't mess with it lightly (I swear I did very powerful things in responder-chain manipulation, so I don't say that out of fear.)
In addition - there is even a simpler method - that does not require changing the binding. In the Interface-builder, select the text field, and select the "Attribute Inspector" tab. You'll see the following:
Checking the red-circled "continuous" will do the trick. This option is basic and older even than binding, and its main use is to allow validator object (a whole new story) to validate the text and change it on the fly, as the user types. When the text-field calls validator calls, it also updates bound values.
I have the following delegate method which is listening for when text changes in an editable field:
-(void)controlTextDidEndEditing:(NSNotification *)aNotification{
Say, I have two NSTextFields declared, how can I find out which is the NSTextField that generated the notification? I want to perform some code when one text field's text did finish editing and other code when the other text field's code finishes editing.
In other words, how can I get the name of the text field that gave the notification?
Thank you!
[aNotification object] is the NSControl (or NSControl subclass) object which posted the notification.
You could use tags and get the tag field of the object, but first you have to force downcast the object from Any to NSTextField so you can access the tag property (an object of "any" doesn't have a "tag" property) like so:
let object = aNotification.object as! NSTextField
then you can check the tag:
if object.tag == 99 { do something }
That's how I addressed the issue in some of the code I'm working on now.
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:#""];
So I am trying pass in parameters to my "buttonClicked" function so that I can dynamically control what happens when you click the button. Every way that I try to do it on my own just breaks my code. I have searched many different sites and answers on stackOverflow, but I can't seem to find an answer. I am fairly new to objective C, especially with functions, So I could really use some help figuring out how to do this. Thanks in advance
Here is my code thus far and what I am trying to do:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
NSLog(#"Hi 1!");
[button addTarget:self action:#selector(buttonClicked:buttonType:buttonID:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(buttonViewXvalue, buttonViewYvalue, buttonViewWidth, buttonViewLength);
[self.view addSubview:button];
Then the Declaration in the Header File:
- (IBAction)buttonClicked:(id)sender theButtonType: (int)buttonType: theButtonID: (int) buttonID;
and the implementation:
- (IBAction)buttonClicked:(id)sender theButtonType: (int)buttonType: theButtonID: (int) buttonID
{
//Here I would use the buttonType and buttonID to create a new view.
NSLog(#"Hi!");
}
You can't use multi-parameter methods with addTarget:action:forControlEvents:. Instead you might set the button's tag, then look up information later based on the tag.
The action you add to UIButton (or any UIControl for that matter) must have a signature like (void)actionName or (void)actionName:(id)sender; as defined by target-action design pattern.
That gives you two simple solutions. One is that each of your buttons calls different (void)actionName-like method, which then calls a more complex method on self and passes the required parameters. Other way is to give each of your buttons a tag property and have them call (void)actionName:(id)sender-like method (they can all call the same one) and then you call the right method with right parameters depending on this tag:
- (void)actionName:(UIButton)sender;
{
if (sender.tag == 1) {
[self firstMethodWithString:someString andNumber:someNumber];
} else if (sender.tag == 2) {
[self secondMethodWithArray:someArray dictionary:someDictionary andColor:someColor];
} // and so on
}
Notice how I changed sender from id to UIButton here. This enables you to call tag without casting and not get a compiler warning, because compiler know you only expect UIButton instances to call this method.
If you really wanted to you could create a separate callback for each button, like:
// In your Whatever.h file
- (IBOutlet)actionButton1:(UIButton *)sender;
- (IBOutlet)actionButton2:(UIButton *)sender;
// In your Whatever.m file
- (IBOutlet)actionButton1:(UIButton *)sender
{
// do button 1 specific stuff
}
- (IBOutlet)actionButton2:(UIButton *)sender
{
// do button 2 specific stuff
}
// etc you get the idea
Then from Interface Builder look at your Whatever.xib file. You can link the "Sent Event" (drag from right side column) of "Touch Up Inside" to any of those actions above which will pop up in "File's Owner" (left column, when you release drag). You can do a different one for each button.
I should mention that generally if these are variants of the same functionality it makes more sense to use the tag property of UIButton.
I have solved this problem with an array of objects: all the parameters are stored in one object, then the object is inserted in the array, finally, the index of the object in the array is passed in the TAG property of the button. This technique works for one or many buttons. I did it for an app that had a list of contacts, where you were able to accept or reject them with buttons, and this buttons were calling the same action method, thanks to the TAG it was possible to know what parameters send to database. Steps:
1- Create a new class : New File, Objective-C class, name it, subclass of NSOBJECT, save it.
2- In the header of this new class declare one property for each parameter.
3- Now go to the IMPLEMENTATION file of the class of the viewcontroller where your button belongs to.
4- Import your new class :
#import "new_class.h"
5- Declare the array in the INTERFACE section :
#interface my_viewcontroller ()
{ NSMutableArray * my_array; }
6- In the VIEWDIDLOAD method create the array as empty :
my_array = [ [ NSMutableArray alloc ] initWithObjects : nil ];
7- In the method where you get the data for the parameters, declare an object of the new class, instantiate it and fill the properties :
new_class * nc;
nc = [ [ new_class alloc ] init ];
nc.param1 = #"abc";
nc.param2 = 123;
nc.param3 = true;
8- Now insert it in the array :
[ my_array addObject : nc ];
9- Store the value 0 in the TAG of the button. You will use this value as index to access the parameters in the my_array[ 0 ] position.
If there are more buttons, for example, from a web service that returns JSON data, just loop through the data creating more instances of the new class and inserting them in the array. Later, for example, in a tableview with dynamic cells and a template cell with buttons, in the method CELLFORROWATINDEXPATH, you will be able to store the INDEXPATH value in the TAG of every button, so these buttons will access their own parameters.
I've been having an interesting problem. I've got both a UIButton and a UITextField, lets call them myButton and myField respectively. Now, when the user presses myButton, it is supposed to save the contents of [myField text] to another variable that we'll call otherVar. Now when I type into myField and hit the return key, everything works fine, however when I press myButton before myField has been left, the string that gets stored in otherVar always looks something like:
<UIButtonContent: 0x4e13c60 Title = (null), Image = <UIImage: 0x4b50980>, Background = (null), TitleColor = UIDeviceWhiteColorSpace 1 1, ShadowColor = UIDeviceWhiteColorSpace 0 0.5>
Does the [myField text] not get set until the user presses the return key, leaving the text field? And also, is there a way to tell if the user has left myField before pressing myButton?
Here is the IBAction code for myButton:
-(IBAction)myButton:(id)sender{
if (![[myField text] isEqualToString:#""]) {
[[[appDelegate moduleList] objectAtIndex:[appDelegate moduleNum]] setOtherVar:[myField text]];
}
}
thanks!
Try adding [myField resignFirstResponder]; before your if statement in the IBAction method. This should commit any of the text edits that have been made, and populate the text property.
You can use notifications to know exactly when a UITextField has changed its value, discussed in the docs here.
More about notifications here.
There are also delegate methods for UITextFields which let you know when editing begins and ends, among other things - docs here.