0

I need help with adding logic to get the static table view cell section index.

I have a plain static UITableView with 2 sections, in each section there are 2 cells with textfields.

I implemented a code for adding a toolbar with prev/next/done butoons to the keyboard.

The prev/next work if the textfields are in section 0, but when tapping next to go to the next textfield which is in the section 1, the app crash.

Where should I put the "if condition" to check the section the textfield reside in ?

here is my .h file

#import <UIKit/UIKit.h>

@interface TextFieldTVCViewController : UITableViewController <UITextFieldDelegate, UIAlertViewDelegate>

@property(strong, nonatomic) IBOutlet UITextField *dep1TextField;
@property(strong, nonatomic) IBOutlet UITextField *arr1TextField;
@property(strong, nonatomic) IBOutlet UITextField *dep2TextField;
@property(strong, nonatomic) IBOutlet UITextField *arr2TextField;

@property(strong, nonatomic) IBOutlet UIToolbar *keyboardToolbar;
@property(strong, nonatomic) IBOutlet UIBarButtonItem *toolbarActionButton;

@property(strong, nonatomic) NSArray *textFields;

- (IBAction) closeKeyboard;
- (IBAction) nextField;
- (IBAction) prevField;

@end

here is my .m file

#import "TextFieldTVCViewController.h"

@interface TextFieldTVCViewController ()

@end

@implementation TextFieldTVCViewController

@synthesize dep1TextField, dep2TextField, arr1TextField, arr2TextField;
@synthesize keyboardToolbar, toolbarActionButton;
@synthesize textFields;


- (void)viewDidLoad
{
 [super viewDidLoad];
 textFields = [[NSArray alloc] initWithObjects:dep1TextField, arr1TextField, dep2TextField, arr2TextField, nil];

}

- (void) textFieldDidBeginEditing:(UITextField *)textField{
[textField setInputAccessoryView:keyboardToolbar];
for (int i=0; i<[textFields count]; i++) {
    if ([textFields objectAtIndex:i]==textField) {
        if (i==[textFields count]-1) {
            toolbarActionButton.title =@"Done";
            [toolbarActionButton setStyle:UIBarButtonItemStyleDone];
        }
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
}
}

- (IBAction) closeKeyboard{
for(UITextField *t in textFields){
    if ([t isEditing]) {
        [t resignFirstResponder];
        break;
    }
}
}

- (IBAction) nextField{
for (int i=0; i<[textFields count]; i++) {

    if ([[textFields objectAtIndex:i] isEditing] && i!=[textFields count]-1) {
        [[textFields objectAtIndex:i+1] becomeFirstResponder];
        if (i+1==[textFields count]-1) {
            [toolbarActionButton setTitle:@"Done"];
            [toolbarActionButton setStyle:UIBarButtonItemStyleDone];
        }else {
            [toolbarActionButton setTitle:@"Close"];
            [toolbarActionButton setStyle:UIBarButtonItemStyleBordered];
        }

        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i+1 inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];


        break;
    }
}

}

- (IBAction) prevField{
for (int i=0; i<[textFields count]; i++) {
    if ([[textFields objectAtIndex:i] isEditing] && i!=0) {
        [[textFields objectAtIndex:i-1] becomeFirstResponder];
        [toolbarActionButton setTitle:@"Close"];
        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i-1 inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
        [toolbarActionButton setStyle:UIBarButtonItemStyleBordered];

        break;
    }
}
}
@end

The site i took the code from for the toolbar:

http://idebuggerman.blogspot.com/2010/08/uitoolbar-for-keyboard-with.html?showComment=1371639814883

Thanks

kupilot
  • 494
  • 1
  • 3
  • 15

1 Answers1

0

I think your approach to keep an array of text fields is not very clean. It results in very complicated code and you have to iterate a lot, which is error-prone.

Instead, use an enum to tag the text fields. Insert the appropriate numbers in storyboard under "tag". On top of your implementation file, define your fields.

typedef enum { 
   Dep1Field = 100, Arr1Field,
   Dep2Field,       Arr2Field, 
   NumberOfFields
} TableFields;

Now you can easily identify the text field in the delegate callbacks and methods. I recommend keeping a reference to the edited text field in an ivar. You can set it in the standard UITextField delegate callbacks.

@implementation ViewController {
    UITextField *_textFieldBeingEdited;
}
//...

The "next" and "previous" logic is easy now:

// next
if (textFieldBeingEdited && textFieldBeingEdited.tag < NumberOfFields-1) {
    [textFieldBeingEdited resignFirstResponder];
    UITextField *nextTextField = 
         (UITextField*)[self.view viewWithTag:textFieldBeingEdited.tag+1];
    [nextTextField becomeFirstResponder]; 
}
Mundi
  • 79,884
  • 17
  • 117
  • 140