2

I have a UITableView that has 2 different customcell definitions. One is a single UITextField and the other has 4 UITextFields

userInteractionEnabled is manually set to enable cell level touch navigation, and I handle the UI interaction within didSelectRowAtIndexPath to the first responder to the relevant cell

This all worked fine when I was using just the one customcell (EditableCustomCell) with one UITextField (editableTextField), but now I have a customcell (LatLonCustomCell) with 4 UITextFields (degrees, minutes, seconds, cartesian), I cannot determine which field has been touched in order to set becomeFirstResponder

(currently I'm defaulting in the first textfield called degrees during debug)

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{      
  [prevField resignFirstResponder];
  prevField.userInteractionEnabled = NO;

  if(indexPath.section == kFirstSection && (indexPath.row == kLatitudeRow || indexPath.row == kLongitudeRow)) {
    LatLonCustomCell *customCell = (LatLonCustomCell *)[MyTableView cellForRowAtIndexPath:indexPath];
    currField = customCell.degrees; // need to set correct field here
  } else {
    EditableCustomCell *customCell = (EditableCustomCell *)[MyTableView cellForRowAtIndexPath:indexPath];
    currField = customCell.editableTextField;
  }

  currFieldIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
  currField.userInteractionEnabled = YES;
  [currField becomeFirstResponder];

}

Izzy Manpo
  • 449
  • 1
  • 3
  • 16
  • UPDATE: Answered my own question, scroll down to see example of how I resolved it ... – Izzy Manpo Sep 16 '12 at 15:01
  • Can you explain why your field is disabled? As it stands, the question reads as "I'm doing this crazy thing, how do I make it work?", and I'm sure you have a good reason for it! – Steven Fisher Sep 16 '12 at 15:06
  • Whilst implementing various textfield based methods for validation (ie. textfieldShouldBeginEditing, textfieldShouldDidBeginEditing, textfieldShouldEndEditing, textfieldDidEndEditing, etc) I had various odd behaviours occurring that prevented me from obtaining the correct UI responses. In order to achieve this, I required the textfield to be disabled in order that the whole cell receive the touch, therefore triggering the `didSelectRowAtIndex` method. During this method I manually enable the textfield and set becomeFirstReponder such that the textfield methods (named above) fire correctly. – Izzy Manpo Sep 16 '12 at 19:11
  • Essentially I am attempting similar functionality to the standard iPhone add contact screen (with a generic tableview to boot) !!! Not one to make life simple for myself :) – Izzy Manpo Sep 16 '12 at 19:13

3 Answers3

1

OK, so for those that come across this with the same or similar problem, I have finally made a breakthrough

I decided that I was going to need to capture the X/Y coordinates of the touch prior to the didSelectRowAtIndexPath being called. This way I could then determine which UITextField the touch occurred in by checking the touch against the "bounds" of the textfield

After some random searching, I found that a VERY easy way of capturing ANY touch event in the viewcontroller (as touchesBegan only occurred in the custom overridden UITableViewCell class and I knew not how to pass this back up the chain Cell > TableView > Scroll View > Controller)

By adding this to the viewDidLoad method:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 1;
// Pass the tap through to the UITableView
tapGesture.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapGesture];

This captures all touches, calling the handleTapGesture method

Then within this method it was simply a case of checking if the touch was within the bounds of the tableview, and if so, determine the indexPath for the point touched and then check against the bounds of the object required, below is a simplified version of what I came up with

-(void)handleTapGesture:(UITapGestureRecognizer *)tapGesture {

  CGPoint tapLoc = [tapGesture locationInView:self.tableView];

  if([MyTableView indexPathForRowAtPoint:tapLoc]) {
    // Tap still handled by the UITableView delegate method

    NSIndexPath *indexPath = [MyTableView indexPathForRowAtPoint:tapLoc];

    if(indexPath.section == 0 && (indexPath.row == kLatitudeRow || indexPath.row == kLongitudeRow)) {
      LatLonCustomCell *customCell = (LatLonCustomCell *)[MyTableView cellForRowAtIndexPath:indexPath];
      UIScrollView *scrollView = (UIScrollView *)self.view;
      CGRect rc;

      // Degrees
      rc = [customCell.degrees convertRect:[customCell.degrees bounds] toView:scrollView];

      if (tapLoc.x >= rc.origin.x && tapLoc.y >= rc.origin.y && tapLoc.x <= (rc.origin.x + rc.size.width) && tapLoc.y <= (rc.origin.y + rc.size.height)) {
        NSLog(@"touch within bounds for DEGREES");
        touchField = customCell.degrees;
      }

// Repeat for other textfields here ....

....

In my code I save the field within touchField, as within the didSelectRowAtIndexPath code, I am already handling prevField/currField values to control the enabling/disabling of userInteractionEnabled and to set the currField as becomeFirstReponder

Hope this proves helpful to someone :)

Izzy Manpo
  • 449
  • 1
  • 3
  • 16
0

In the past when I have needed to check if a text box has been touched I checked if YourTextField.text.length > 0. If it is you can set becomeFirstResponder. Hope this helps.

Douglas
  • 2,524
  • 3
  • 29
  • 44
  • No, that wont work. As I am setting field.userInteractionEnabled = NO, only the cell receives the touch action, as in the code above. I need to be able to determine which field out of the 4 to enable programatically – Izzy Manpo Sep 15 '12 at 11:03
0

Have you thought about using NSNotificationCenter to request notifications for UITextFieldTextDidBeginEditingNotification?

in viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldBeganEditing) 
                                             name:UITextFieldTextDidBeginEditingNotification object:nil];

and then something like

-(void) textFieldBegainEditing: (NSNotification*) notification {
  // [notification object] will be the UITextField
  // do what you need to do with it (resign, become first responder)
}
ToddB
  • 2,490
  • 3
  • 23
  • 40
  • Thanks, but textFieldDidBeginEditing doesn't fire as due to having field.userInteractionEnabled = NO set for the UITextField, it is the UITableViewCell that receives the touch notification, to all intents and purposes as far as the UI is concerned, the field is never touched (ie. its effectively hidden from being touched) – Izzy Manpo Sep 16 '12 at 12:19