how to increment or decrement textfield value using uistepper? - ios

I currently have a UITextField which has some value in it and also i have a UIStepper besides it.
I want to know how to use the UIStepper so as increment/decrement the textfield value.
CODE:
the value changed action of the UIStepper
1st I tried this
- (IBAction)changedX:(UIStepper*)sender
{
double value = [sender value];
self.XStepper.value=[self.XCoordinate.text doubleValue];
self.XCoordinate.text=[NSString stringWithFormat:#"%g",value];
NSLog(#"%f",value);
}
then i changed it to this:
if ([sender value]==1) {
double temp= [self.XCoordinate.text doubleValue];
temp=temp+1;
self.XCoordinate.text=[NSString stringWithFormat:#"%g",temp];
}
else
{
double temp= [self.XCoordinate.text doubleValue];
temp=temp-1;
self.XCoordinate.text=[NSString stringWithFormat:#"%g",temp];
}
i am not understanding how do i take the current UITextField value and update it in UIStepper so that current value should be incremented/decremented accordingly.
Thanks

You should not do it in this method. From what I understand, you want to be able to change the text in the UITextfield from the UIStepper and also, if the text in the UITextfield changes, you want to update the Stepper.
You should use the Value Changed event of the UIStepper to update the text field, but when you want to update the actual stepper from the text field, you should have another method.
- (void)updateStepper:(UIStepper *)stepper fromTextField:(UITextField *)textfield {
NSInteger value = [textfield.text integerValue];
[stepper setValue:value];
}

try this code:
- (void)viewDidLoad;
{
[self.stepper setValue:10];
// steppr get valye from textfiled
}
- (IBAction)stepperChanged:(UIStepper *)sender
{
NSUInteger value = sender.value;
NSLog(#"%d",value);
NSLog(#"%#",self.XCoordinate.text);
self.XCoordinate.text = [#(value) stringValue];
[self.stepper setValue:value];
}
-(void)textFieldDidEndEditing:(UITextField *)textField;
{
[self.stepper setValue: self.XCoordinate.text.doubleValue];
}
hope it help You

Set the stepper.value to the default value in viewDidAppear/viewDidLoad

This alternative worked for me. Every time I edit the textfield the stepper.value is set. This way when I tap the stepper it has works with the value it already has, the textfield value or it's own value.
- (IBAction)didTapStepper:(UIStepper *)sender {
self.textFieldName.text = [NSString stringWithFormat:#"%ld", (long)sender.value];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if(textField == self.textFieldName){
self.stepperName.value = [[NSString stringWithFormat:#"%#%#", self.textFieldName.text, string] doubleValue];
}
return YES;
}
EDIT: Don't forget to add the Delegate UITextFieldDelegate,
and assign yourself to it.
self.textFieldName.delegate = self;

Related

How to set a range of numbers for textfield in iOS?

I want to set a range i.e between $350000 & $800000 for a text field. If the entered number is less than this range then an alert message should pop up. Plz help
In Objective-C using NSNumberFormatter you can use like this:
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.minimum = #10;
nf.maximum = #20;
NSNumber *a = [nf numberFromString:#"12"];
NSNumber *b = [nf numberFromString:#"22"];
//if the number is beyond the range, it will return nil, so in above b is nil
//so the following check will show the log and alert
if (!a || !b) {
NSLog(#"Either of them is out of range");
//show the UIAlert here
}
EDIT:
You should call the above in following scenarios:
User enter a value and does some action. In the beginning of the action use the above.
Or every time the user enters and moves away from the textfield, then call the above in textFieldDidEndEditing: delegate method of UITextField.
Note: Since your number has $ prefixed, please make sure you set the currency style in nf as well, instead of trimming it.
Use - (void) textViewDidEndEditing:(UITextView *)textView method to check the intergerValue of text and if it doesn't match your requirement show the popup.
If wanna check it on the go use - (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
NSString *finalText = [textView.text stringByAppendingPathComponent:text];
finalText = [finalText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//enable button
if ([finalText integerValue] < 350000 || [finalText integerValue] > 850000) //do what you wanna do
Make sure $ is out of textfield or you remove it before using integerValue.
This can be helpfull
-(void)viewDidLoad
{
[txt addTarget:self action:#selector(CheckingMethod:) forControlEvents:UIControlEventValueChanged];
}
-(IBAction)CheckingMethod:(id)sender
{
if(txt.text.length>9) {
//your popupview
}
else{
}
}

VENTokenField hold backspace key to delete tokens

While trying to allow multi token deletions, as user holds the backspace key in VENTokenField to act the same as the native email app, or messages app, I have come across many problems...
First, I can only detect one tap on the backspace key from the initial code the VENToken's UITextField subclass offer (which is technically touching private API) - (BOOL)keyboardInputShouldDelete:(UITextField *)textField. That is fine, but not helpful for detecting long press on backspace button, which only works while you actually have characters in a certain UITextField, and not while the UITextField is empty such as in our case.
I have also came across this blogpost which suggest another approach of accessing more of the private API, however, does not offer solution to my problem. As it's not documented, I was wondering if there is a valid way to detect this event at all?
I've resolved it by first, comment out anything that was in VENBackspaceTextField class'
keyboardInputShouldDelete:(UITextField *)textField
Then, added 2 consts in VENTokenField header:
NSString * const kTextEmpty = #"\u200B"; // Zero-Width Space
NSString * const kTextHidden = #"\u200D"; // Zero-Width Joiner
Everytime the token becomes first responder, make sure the textField has the empty text:
- (void)inputTextFieldBecomeFirstResponder {
[self.inputTextField becomeFirstResponder];
if (self.tokens.count) {
[self.inputTextField setText:kTextEmpty];
}
...
}
And set it to hidden when cursor is not visible:
- (void)setCursorVisibility {
NSArray *highlightedTokens = [self.tokens filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(VENToken *evaluatedObject, NSDictionary *bindings) {
return evaluatedObject.highlighted;
}]];
BOOL visible = [highlightedTokens count] == 0;
if (visible) {
[self inputTextFieldBecomeFirstResponder];
} else {
[self.invisibleTextField becomeFirstResponder];
[self.invisibleTextField setText:kTextHidden];
}
}
Then, modified the textField Delegate method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (self.tokens.count && [string isEqualToString:#""] && [textField.text isEqualToString:kTextEmpty]){
VENToken *lastToken = [self.tokens lastObject];
lastToken.highlighted = YES;
[_inputTextField setText:kTextHidden];
_inputTextField.alpha = 0.0;
return NO;
}
if ([textField.text isEqualToString:kTextHidden]){
[self deleteHighlighted];
[self unhighlightAllTokens];
return (![string isEqualToString:#""]);
}
//If there are any highlighted tokens, delete
[self deleteHighlighted];
return YES;
}

UITextFieldDelegate, checking if textFields have text in it

i have a little problem.
There are two textFields in my TableView which set the property of an object. In order to do so i want to force the user to write something in the textField before the string is actually been set to the object. So basically a simple ([textField.text length] > 0) thing.
But i want that the user have to write strings in both the two textFields to finally enable the "Done"-Button.
I solved this earlier but with only one text Field with the following UITextFieldDelegate method.
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newText = [theTextField.text stringByReplacingCharactersInRange:range withString:string];
self.doneBarButton.enabled = ([newText length] > 0);
return YES;
}
My solution for the new problem, so now with two textFields is this one:
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newText = [theTextField.text stringByReplacingCharactersInRange:range withString:string];
if ([theTextField.placeholder isEqualToString:#"textField1"]) {
if ([theTextField.text length] > 0) {
enabledVokabel = YES;
} else {
enabledVokabel = NO;
}
}
if ([theTextField.placeholder isEqualToString:#"textField2"]) {
if ([theTextField.text length] > 0) {
enabledUebersetung = YES;
} else {
enabledUebersetung = NO;
}
}
self.doneBarButton.enabled = (enabledVokabel && enabledUebersetung);
return YES;
}
So i want the doneBarButton been enabled when both of the textFields (textField1 and textField2) are filled with text. But i want it that way that if the user has deleted the text he/she just wrote in the doneBarButton is disabled as soon as the textFields are empty.
It doesn't work that way. Do you have a solution? Or maybe a better way to solve it?
Either just connect value changed in interfacebuilder to a IBAction method in any of the classes you have in your view. Or you can do it in code with:
[textField addTarget:self
action:#selector(myIBActionMethod:)
forControlEvents:UIControlEventEditingChanged];
And check the length of the input.
You can of hook up both textfields to the same method and check the length of both textfields every time its called if you have IBOutlets to them both.
I'd keep a reference for both UITextViews, lets say.-
IBOutlet UITextView *textView1;
IBOutlet UITextView *textView2;
properly linked to your xib/storyboards. Also, I'd rather use
- (void)textViewDidChange:(UITextView *)textView
callback. According to shouldChangeCharactersInRange docs, it looks like this method is called before actually changing the text.
As for the enabled condition, it would look something like this.-
self.doneBarButton.enabled = [textView1.text length] > 0 && [textView2.text length] > 0;

clearing a UITextField when the user starts typing

short version: How can I make a UITextField box remove all content on the users first keypress? I don't want the info removed until the user starts typing something. ie, clearing it on begin edit is not good enough.
long version: I have three UITextField that loop around (using the return key and catching the press in the "shouldReturn" method. There is text already in the UITextField, and if the user doesn't type anything and just goes to the next UITextField, the value should stay (default behaviour).
But I want it that if the user starts typing, it automatically clears the text first. Something like having the whole field highlighted, and then typing anything deletes the fiels and then adds the user keypress.
"Clear when editing begins" is no good, because the text is immediately cleared on the cursor appearing in the field. That's not desired. I thought I could use the placeholder here, but that doesn't work as a default, and I can't find a default value property. The Highlighted and Selected properties don't do anything in this regard either.
There is a delegate method called
textFieldDidBeginEditing:(UITextField*) tf{
tf.startedEdinting = YES;
}
textFeildDidEndEditing: (UITextField*) tf {
tf.startedEditing = NO;
}
Add startEditing in a category to UITextField.
Then if value changes clear the field:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.startEditing){
textField.text = string;
} else {
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
}
}
You can add the property to the UITextField category in the following way:
.h
#property (nonatomic, assign) BOOL startEditing;
.m
#dynamic startEditing;
- (void) setStartEditing:(BOOL)startEditing_in{
NSNumber* num = [NSNumber numberWithBool:startEditing_in];
objc_setAssociatedObject(self, myConstant, num, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL) startEditing{
NSNumber* num = objc_getAssociatedObject(self, myConstant);
return [num boolValue];
}
Declare a BOOL variable in your .h file like.
BOOL clearField;
And implement the delegate methods like:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
clearField = YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
clearField = NO;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
clearField = NO;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(clearField)
{
textField.text = #""
clearField = NO;
}
}
I want to thank people for their answers, I implemented both of the main methods described here and both worked flawlessly. But I have since come across a much simpler, nicer answer and involves only one line of code :)
In the textField's didBeginEditing method, place [self.textField selectAll:self]; or [self.textField selectAll:nil];
The original answer I found had selectAll:self but this shows the cut/copy/paste menu. If you send nil instead of self the menu doesn't appear.
Adding this one line of code highlights the text on entering the textField (so gives the user a visual cue), and only removes everything once a key is pressed.
Another solution that fulfils the same purpose is by simply using a text field placeholder which is defined as:
The string that is displayed when there is no other text in the text field.
So as soon as the user starts typing, the placeholder text disappears.
That's something you can set from the storyboard, or programmatically. (Yes it took me two hours trying to figure it the harder way.. when the solution was literally one line change of code).
If you want to clear the text one the user interacts with it, there is an option in interface builder to where you can set the text field to "Clear when editing begins."
Try to use the following method.
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {
if(isFirsttime==YES)
{
textfield.text==#"";
isFirsttime=NO;
}
return YES;
}
Declare and initialize a NSString variable for your textField's initial text
NSString *initialText=#"initial text";
Then implement methods:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
if(textField.text isEqualToString:initialText)
{
textField.text=#"";
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if(textField.text isEqualToString:#"")
{
textField.text=initialText;
}
}

UITextField clear when selected, but also restore data if nothing is input

I have a table with UITextFields, and I want to make it so that when a textfield is selected, the current info is cleared (to allow new input), but if the user decides (after selecting) that they don't want to change it, I want them to be able to click elsewhere and the data from before reappears in the textfield.
Is there an easy way to do this?
A good way to do this that's nice and user friendly is to use the placeholder property. Set up your viewController as the textfield's delegate (as described by Andeh) then add the following code:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
textField.placeholder = textField.text;
textField.text = #"";
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField.text.length == 0) {
textField.text = textField.placeholder;
}
textField.placeholder = #"";
}
And you're done. If you have multiple UITextFields on the page and you don't want this behaviour for all of them you can add a check to the methods above.
In the textFieldDidBeginEditing delegate method, save the current value to a persisting variable before clearing the UITextField. Then in the didFinishEditing delegate method, if the new length of the user input is 0 set the text back to the stored value!
UITextField Delegate docs for reference.
First I think you have two sets of behaviors here.
The text field must clear the value when you begin editing. This exists: -clearsOnBeginEditing.
The text field must restore the previous text if text is empty. Subclassing seems the better solution.
Here is a possible sample class:
// MyRestoringTextField.h
#interface MyRestoringTextField : UITextField
#end
// MyTextField.m
#interface MyRestoringTextField ()
#property (strong, nonatomic) NSString *previousText;
#end
#implementation MyRestoringTextField
- (BOOL)becomeFirstResponder
{
BOOL result = [super becomeFirstResponder];
self.previousText = self.text;
return result;
}
- (BOOL)resignFirstResponder
{
BOOL result = [super resignFirstResponder];
if (self.text.length == 0)
self.text = self.previousText;
return result;
}
#end
Hope that helps.
To clear and then restore a textField if you fail to make an entry, use the following delegates as such:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[[NSUserDefaults standardUserDefaults] setObject:textField.text forKey:kTextFieldIdentifier];
textField.text = #"";
}
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if ([textField.text isEqualToString:#""])
textField.text = [[NSUserDefaults standardUserDefaults]
stringForKey:kTextFieldIdentifier];
return YES;
}
As of iOS 8.1, textFieldDidBeginEditing is already receiving a cleared text. You should use
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField
to initialized the placeholder field.

Resources