I have a view with two text fields and two segmented controls. I want each text field to become editable when its corresponding segmented control is selected.
Here is the approach I'm using:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == _textField) {
if (_segmentedControl.selectedSegmentIndex == 0 ||
_segmentedControl.selectedSegmentIndex == 1 ||
_segmentedControl.selectedSegmentIndex == 2 ||
_segmentedControl.selectedSegmentIndex == 3) {
return YES;
} else {
return NO;
}
if (textField == _textFieldTwo) {
if (_segmentedControlTwo.selectedSegmentIndex == 0 ||
_segmentedControlTwo.selectedSegmentIndex == 1) {
return YES;
} else {
return NO;
}
}
}
}
This works for the first segmented control and textfield, but the second text field remains editable regardless of the condition of the second segmented control.
Can anyone tell me where I'm going wrong?
Thanks
The IFs are not nested correctly.
if (textField == _One){
if( 0<= selectedIndex < 4) {
//do something
} else {
return no;
}
if (textField == _Two){
// other stuff
}
}
Can you see that the if(textFieldTwo) is inside the if(textFieldOne) ?
Looks like a simple logic error to me. Your:
if (textField == _textFieldTwo) {
should really be an else if on the first if.
Simply change it to:
} else if (textField == _textFieldTwo) {
and it should start working.
Related
I have a form with more than 10 text fields. I want to check if all are entered. I know the following way to check the same
if ([_fName.text isEqualToString:#""])
Is it the best way even if we have more than 10 text fields? or is there any simpler way?like assign something in storyboard or something?
You can conform your view controller to <UITextFieldDelegate> protocol and implement:
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([textField.text isEqualToString:#""]) {
// your code
}
}
In addition your can check which exactly textField was changed and apply custom validation logic:
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == self._fName) {
// your code
}
}
You can use textFieldDidEndEditing for tracking text:
- (void)textFieldDidEndEditing:(UITextField *)textField {
switch (textField.tag) {
case NameFieldTag:
// do something with this text field
break;
case EmailFieldTag:
// do something with this text field
break;
}
}
I suggest you do something like below. Note, you will probably want to do more than validate if something exists in the fields. You might want to check validity of dates, numbers, etc as well.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
// assuming you have a save bar button or equivalent
// disable it or change it from 'Edit' to 'Save' when you start changing textFields
self.navigationItem.rightBarButtonItem.enabled = NO;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// validate form
if (_textField1.text.length > 0 &&
_textField2.text.length > 0 &&
_textField3.text.length > 0 &&
_textField4.text.length > 0 &&
_textField5.text.length > 0)
{
// Re-enable your bar button or change it from 'Edit' to 'Save'
// if form validates
self.navigationItem.rightBarButtonItem.enabled = YES;
}
}
I'm trying to use a Segmentcontroller.
When a button is press my callback gets call,
but when i use .selectedSegmentIndex to see what button was press, it returns a zero.
code
-(IBAction)changeSeg{
int g;
g=Segment.selectedSegmentIndex;
if(Segment.selectedSegmentIndex == 0){
UpperLower=0;
}
if(Segment.selectedSegmentIndex == 1){
UpperLower=1;
}
}
I think the method should look like this
- (IBAction)ChangeSeg:(UISegmentedControl *)sender {
if(sender.selectedSegmentIndex == 0){
UpperLower=0;
} else if(sender.selectedSegmentIndex == 1){
UpperLower=1;
}
}
The sender will have the selectedSegmentIndex that was chosen.
I have a simple application where the user inputs information into a series of UITextFields and a few other components in order for the app to populate with information.
I have 4 UITextFields (Name, Event, Subevent and Amount), 1 UITextView (notes), a UIDatePicker and a UISegmentedControl (Status).
The Name, Event, Amount and Status are required, where the Subevent and Notes are optional.
I've put some logic to disable the "Save" BarButtonItem if the the required fields are not filled in; however I'm noticing my logic is not working correctly.
Here's the logic:
- (void) checkTextFields
{
if (([self.nameTextField.text length] != 0 && [self.itemTextField.text length] != 0 && [self.occasionTextField.text length] != 0 && [self.isReceivedSegment selectedSegmentIndex] == 0) || [self.isReceivedSegment selectedSegmentIndex] == 1)
{
NSLog(#"This shouldn't be run if not every field is filled in");
self.saveButton.enabled = TRUE;
}
else
{
NSLog(#"Run");
self.saveButton.enabled = FALSE;
}
}
I'm calling this from the viewDidLoad:
self.saveButton.enabled = FALSE;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkTextFields) name:UITextFieldTextDidChangeNotification object:nil];
[self.isReceivedSegment addTarget:self action:#selector(checkTextFields) forControlEvents:UIControlEventValueChanged];
Problem
The problem is: if I enter the Name, Event and Select a Segment in the SegmentedControl, it SHOULD NOT enable the Save button because the Amount is not filled in.
The same applies if I put in the Name, Amount and Select a Segment, the Save button should not be filled in because the Event is not filled in, yet, it is in both of those situations.
Am I missing something obvious?
Try this:
- (void) checkTextFields
{
if ([self.nameTextField.text length] != 0 && [self.itemTextField.text length] != 0 && [self.occasionTextField.text length] != 0 && ([self.isReceivedSegment selectedSegmentIndex] == 0 || [self.isReceivedSegment selectedSegmentIndex] == 1))
{
NSLog(#"This shouldn't be run if not every field is filled in");
self.saveButton.enabled = TRUE;
}
else
{
NSLog(#"Run");
self.saveButton.enabled = FALSE;
}
}
The way you have implemented your conditions, with the parentheses, it will evaluate true when your selectedSegmentIndex = 1, regardless of the other conditions. Moving around the parentheses like so should work.
Notice that I have moved the parentheses to surround the OR portion of your conditions.
EDIT add these lines to your view did load method to have the form be checked after editing any text field.
[nameTextField addTarget:self action:#selector(checkTextFields) forControlEvents:UIControlEventEditingChanged];
[itemTextField addTarget:self action:#selector(checkTextFields) forControlEvents:UIControlEventEditingChanged];
[occasionTextField addTarget:self action:#selector(checkTextFields) forControlEvents:UIControlEventEditingChanged];
I have four text fields in a ViewController, and want to disable the keyboard for two of them (textField1 and textField2).
I have tried implementing the following after assigning the text fields as delegates in viewDidLoad
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField) {
if ([self.textField1 isTouchInside] || [self.textField2 isTouchInside] {
return NO;
} else {
return YES;
}
}
However, this disables the keyboard for the ViewController completely, so it will not appear when trying to edit textField3 and textField4. How can I get around this problem?
For example, is there a way to refresh the run textFieldShouldBeginEditing method again after editing ends on a textField?
Also, I know I can create a label to accomplish something similar, but I would prefer to use a text field in my case.
EDIT: So I left out a big detail. I am firing an IBaction when pressing textField1 and 2. However, Lootsch's answer gave me an idea.
In the textField1/2Pressed IB action, I ran the textfield.enable:NO methods, then I re-enabled them when I fired a second action which submitted data to the textfields, such as below
- (IBAction)textField1Pressed:(id)sender {
self.textField.Enabled = NO;
}
- (IBAction)submitToTextField1:(id)sender {
self.textField.text = #"blah blah";
self.textField.Enabled = YES;
}
Albeit, this requires having two entering an exiting actions, but it worked for me. Also, I did not have to manipulate the textFieldShouldBeginEditing method with this solution.
You should disable these two textFields (in code or via IB) or you can disable the user interactions (different appearance, same function):
textField3.enabled = NO;
textField4.enabled = NO;
Or:
textField3.userInteractionEnabled = NO;
textField3.userInteractionEnabled = NO;
The second approach won't change the appearance of the UITextFields, while the first will indicate, that these TextFields are disabled.
something like should do
if (textField==textField1 || textField==textField2) [textField resignFirstResponder];
Please try this
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField==self.textField1 || textField==self.textField2)
{
return NO;
}
else
{
return YES;
}
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)mytextField
{
if((mytextField.tag == 104) || (mytextField.tag == 105) || (mytextField.tag == 106))
{
if(mytextField.tag == 104)
{
point = 50;
// if(textField1.tag == 4)
{
[self showDatePickerWithTitle:#"Select DOB"];
return NO;
}
//
}
}
else
{
retutn YES;
}
//you can also try this piece of code.With tag property of textfield.And make sure your tag is not zero,because the default tag is 0 for the main view.
I can't get the return key in my UITextField's to work!
I have quite a lot of UITextField's so can someone give a short bit of code?
If you have a lot of text fields and you want the return key to bring up the next textfield. So the user can enter data quickly. Then set the set the delegate for each textfield to be your view controller with
textField.delegate = self;
make sure your view controller adopts the UITextFieldDelegate protocol by putting this in the interface declaration
<UITextFieldDelegate>
then use the textFieldShouldReturn method
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField == self.Field1) {
[self.Field2 becomeFirstResponder];
}
else if (textField == self.Field2) {
[self.Field3 becomeFirstResponder];
}
else if (textField == self.Field3) {
[self.Field4 becomeFirstResponder];
}
else if (textField == self.Field4) {
[self.Field5 becomeFirstResponder];
}
else if (textField == self.Field5) {
[self.Field5 resignFirstResponder];
}
return YES;
}
Try this
- (IBAction)textFieldDoneEditing:(id)sender
{
[sender resignFirstResponder];
}
You will have to connect this to all the text fields you have. Use the Did End On Exit option when connecting to the File's Owner.
check that the textField.delegate = self; where self is current UIViewController is set and then check if you are resigning the textfield by: [textField resignFirstResponder];