在自定义的UITableViewCell中访问UITextField

12

我在IB中创建了一个带UITextField的UITableViewCell(以及相关的UITableViewCell子类,.m & .h)。这个UITextField被连接到UITableViewCell子类中的IBOutlet,并具有属性。在我的表视图控制器中,我使用以下代码使用此自定义单元格:

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"textfieldTableCell"];
    if (cell == nil) {
        // Create a temporary UIViewController to instantiate the custom cell.
        UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"TextfieldTableCell" bundle:nil];
        // Grab a pointer to the custom cell.
        cell = (TextfieldTableCell *)temporaryController.view;  
        // Release the temporary UIViewController.
        [temporaryController release];
    }

    return cell;

}

UITextField 显示正常,点击后键盘如预期弹出,但我该如何访问(获取 .text 属性)每行包含的 UITextField?同时,我该如何处理 UITextFields 的 'textFieldShouldReturn' 方法?

6个回答

22

我认为OP想要了解的是如何在用户输入数据后访问UITextField的值。根据@willcodejavaforfood的建议,在创建单元格时不会立即可用。

我一直在实施表单并尝试使其尽可能用户友好。这是可行的,但请注意,根据您拥有的UITableViewCells / UITextFields数量,它可能会变得非常复杂。

首先回答您有关访问UITextField值的问题:

1)将您的视图控制器设为<UITextFieldDelegate>

2)实现以下方法:

- (void) textFieldDidEndEditing:(UITextField *)textField {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(CustomCell*)[[textField superview] superview]]; // this should return you your current indexPath

        // From here on you can (switch) your indexPath.section or indexPath.row
        // as appropriate to get the textValue and assign it to a variable, for instance:
    if (indexPath.section == kMandatorySection) {
        if (indexPath.row == kEmailField) self.emailFieldValue = textField.text;
        if (indexPath.row == kPasswordField) self.passwordFieldValue = textField.text;
        if (indexPath.row == kPasswordConfirmField) self.passwordConfirmFieldValue = textField.text;
    }
    else if (indexPath.section == kOptionalSection) {
        if (indexPath.row == kFirstNameField) self.firstNameFieldValue = textField.text;
        if (indexPath.row == kLastNameField) self.lastNameFieldValue = textField.text;
        if (indexPath.row == kPostcodeField) self.postcodeFieldValue = textField.text;
    }   
}

我也使用类似的语法来确保当前编辑的字段是可见的:

- (void) textFieldDidBeginEditing:(UITextField *)textField {
    CustomCell *cell = (CustomCell*) [[textField superview] superview];
    [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}

最后,你可以类似的处理textViewShouldReturn:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(CustomCell*)[[textField superview] superview]];
    switch (indexPath.section) {
        case kMandatorySection:
        {
            // I am testing to see if this is NOT the last field of my first section
            // If not, find the next UITextField and make it firstResponder if the user
            // presses ENTER on the keyboard
            if (indexPath.row < kPasswordConfirmField) {
                NSIndexPath *sibling = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
                CustomCell *cell = (CustomCell*)[self.tableView cellForRowAtIndexPath:sibling];
                [cell.cellTextField becomeFirstResponder];
            } else {
                // In case this is my last section row, when the user presses ENTER, 
                // I move the focus to the first row in next section
                NSIndexPath *sibling = [NSIndexPath indexPathForRow:kFirstNameField inSection:kOptionalSection];
                MemberLoginCell *cell = (MemberLoginCell*)[self.memberTableView cellForRowAtIndexPath:sibling];
                [cell.cellTextField becomeFirstResponder];
            }
            break;
        }           
        ...
}

回头在我Mac上试一试,感谢Rog的建议。不知道苹果是如何做到这一点的,例如Settings应用程序,我原以为它会更加简单/干净。我想他们可能会用完全不同的方式和代码来实现。 - Darthtong

8
在cellForRowAtIndexPath方法中,加入以下代码:
yourTextField.tag=indexPath.row+1; //(tag must be a non zero number)

然后通过以下方式访问textField:

UITextField *tf=(UITextField *)[yourView viewWithTag:tag];

2

有一种更简单的方法可以解决这两个问题:

1. 为单元格创建自定义 UITableViewCel 类 (例如,textfieldcell)。

2. 现在,在 textfieldcell.h 文件中调用 textFieldDelegate。

3. 在 textfieldcell.m 文件中编写 textFieldDelegate 方法。

-(BOOL)textFieldShouldReturn:(UITextField *)textField;

-(void)textFieldDidEndEditing:(UITextField *)textField;

现在,在(第一个问题)
 -(BOOL)textFieldShouldReturn:(UITextField *)textField             
 {          
      [self.mytextBox resignFirstResponder];           
      return YES;        
 }
5.(第二个问题)
-(void)textFieldDidEndEditing:(UITextField *)textField
{
   nameTextField = mytextBox.text;
}

6.在MaintableViewController中创建一个自定义代理方法

@protocol textFieldDelegate <NSObject>
-(void)textName:(NSString *)name;
 @end

7. 在MaintableViewController.m文件中编写委托方法的实现:

-(void)textName:(NSString *)name{
    Nametext = name;
    NSLog(@"name = %@",name);
}

8.在单元格类中调用委托方法,并在didend方法中传递变量。

9.现在,在uitableview中初始化单元格时,将self分配给cell.delegate。

10.就是这样,你已经从textfield传递了变量到主视图,现在可以随意处理该变量。


1
这是我在Swift中如何获得自定义 UITableViewCell 内部的 UITextField 文本的方法。 我通过访问另一个具有 @ IBAction 的自定义 UITableViewCell 中的 UIButton 来实现此目的,该自定义单元格也位于我的 UITableViewController 上。 尽管我只有一个 UITableViewController 部分,但这并不重要,因为您可以轻松地自己设置和分配它。
@IBAction func submitButtonTapped(sender: UIButton) {
    print("Submit button tapped")

    let usernameCell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0)) as! UsernameTableViewCell
    print("Username: \(usernameCell.usernameTextField.text)")
}

每当我点击我的UIButton时,它会给我UITextField内文本的更新值。

这个非常完美,谢谢你!我使用以下代码:func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {let entryCell = self.tblMetaDetails.cellForRow(at: NSIndexPath(row: 0, section: 1) as IndexPath) as! tvcNewMetaDetailsentryCell.txtEntryView.text = Ingredients[indexPath.row]index = indexPath} - captain_haddock

0
如果您已经为自定义单元格创建了一个类,我建议您针对该类进行操作。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCustomCell* cell = (MyCustomCell *) [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"MyCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = (MyCustomCell *) [topLevelObjects objectAtIndex:0];
    }

    // This is where you can access the properties of your custom class
    cell.myCustomLabel.text = @"customText";
    return cell;
}

0

这个教程对我很有帮助。你可以通过标签引用任何需要的对象。

在Storyboard中拖动UIImageViewUITextField等控件,并将标签设置为100(或其他你想要的数字),然后在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中使用标签来引用它。

这里有一些你可以做的事情,只需记得在Storyboard中设置标签:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

// Configure the cell...
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

 UITextField *tField = (UITextField *)[cell viewWithTag:100];

return cell;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接