菜鸟教程小白 发表于 2022-12-12 14:01:49

ios - 在 iOS 中,如何在两个单元格中的文本字段之间切换?


                                            <p><p>我有一个使用自定义单元格的 TableView 的应用程序,每个单元格都包含一个文本字段。当用户点击一个单元格时,我想将相应的 textField 置于编辑模式。如果另一个单元格的 textField 已经处于编辑模式,我需要让它 resignFirstResponder 以便我可以保存它的数据,然后使新单元格的 textField 成为 FirstResponder。但是当我在新单元格的 textField 上调用 becomeFirstResponder 时,它返回一个零,表示失败。这似乎是一种困惑的处理方式,但我还没有找到更好的方法。</p>

<p>这是我的 TableViewController 文件的全文,其中去除了很多杂乱无章的内容:</p>

<pre><code>//TEST_TVC.h
//TVC_Test
#import &lt;UIKit/UIKit.h&gt;
@interface TEST_TVC : UITableViewController &lt;UITextFieldDelegate&gt;
@end


//TEST_TVC.m
//TVC_Test
#import &#34;TEST_TVC.h&#34;
@interface TEST_TVC ()

@property (strong, nonatomic) NSMutableArray * TestData;
@property (strong, nonatomic) UITextField * fieldBeingEdited;
@property (assign, nonatomic) NSInteger cellIndex;
@property (strong, nonatomic) UITableViewCell * cellContainingField;

@end

@implementation TEST_TVC

- (id)initWithStyle:(UITableViewStyle)style
{
    self = ;
    if (self) {
      // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    ;

    // Init data for testing the TableView
    self.TestData = ;
    for (int i=0; i&lt;25; i++) {
      NSString * title = ;
      NSArray * data = ;
      ;
    }
    self.fieldBeingEdited = NULL;
    self.cellContainingField = NULL;
    self.cellIndex = -1;
}

- (void)didReceiveMemoryWarning
{
    ;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.TestData.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Configure the cell...
    NSString *CellIdentifier = @&#34;TVCell&#34;;
    NSString * titleText;
    NSString * detailText;
    NSString * detailPlaceholder = @&#34;none&#34;;

    // Get the data for this row
    int rowNumber = indexPath.row;
    NSArray * cellData = self.TestData;
    titleText = cellData;
    detailText = cellData;
    //NSLog(@&#34;cellForRow..., entered row=%d, titleText=%@, detailText=%@&#34;, rowNumber, titleText, detailText);

    // Retrieve a pre-built cell to fill in the blanks
    UITableViewCell *cell = ;
    UILabel * cellTitle = (UILabel *);
    cellTitle.text = titleText;
    UITextField * cellDetail = (UITextField *);
    NSLog(@&#34;cellForRow.. reusing cell with Title=%@ and Detail=%@&#34;, cellTitle.text, cellDetail.text);
    NSLog(@&#34;cellForRow.. intended Title=%@, intended Detail=%@&#34;, titleText, detailText);
    if (cellDetail == NULL) {
      NSLog(@&#34;cellForRow..; cellDetail = NULL *******************************************&#34;);
    }

    // Set default configuration of the cellData UITextField here, and make exceptions later
    cellDetail.placeholder = @&#34;&#34;;
    cellDetail.text = @&#34;&#34;;
    cellDetail.borderStyle = UITextBorderStyleRoundedRect;
    cellDetail.userInteractionEnabled = NO;
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.userInteractionEnabled = YES;

    // Configure the cell...
    // based on the data type of the cell&#39;s contents

    // Set the cell&#39;s editable textField
    if ( ) {
      cellDetail.text = @&#34;&#34;;
      cellDetail.placeholder = detailPlaceholder;
    } else {
      cellDetail.text = detailText;
    }
    cellDetail.keyboardType = UIKeyboardTypeASCIICapable;
    cellDetail.autocapitalizationType = UITextAutocapitalizationTypeWords;

    return cell;
}


#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    int rowNumber = indexPath.row;
    ;
    NSLog(@&#34;didSelectRow.. entered; row=%d, cellData=%@&#34;, rowNumber, self.TestData);
    // The selected cell contains a textField with content to be edited
    // If another cell&#39;s textField is currently being edited, save its data before proceding
    UITableViewCell * cell = ;
    UITextField * cellDetail = (UITextField *);
    NSLog(@&#34;didSelectRow..: curently editing cell at [%p], selected cell at [%p]&#34;, self.fieldBeingEdited, cell);
    // if a textField is still in edit mode, show the Responder status of the cell and all in it
    if ( self.fieldBeingEdited != NULL ) {
      ;
    }

    if ( self.fieldBeingEdited == NULL ) {
      NSLog(@&#34;didSelectRow..: no field is being edited.&#34;);
    } else if ( cellDetail == self.fieldBeingEdited ) {
      // the cell selected is the same one being edited
      if ( ! ) {
            // fieldBeingEdited is NOT the firstResponder. Try to make it the firstResponder.
            BOOL becameFirstResponder = ;
            NSLog(@&#34;didSelectRow..: textField at [%p] returned %d from becomeFirstResponder.&#34;, self.fieldBeingEdited, becameFirstResponder);
            ;
      }
    } else if ( cellDetail != self.fieldBeingEdited ) {
      // the cell selected is NOT the one being edited. Save the edited data and release the keyboard
      NSLog(@&#34;didSelectRow..: field in cell with index=%d is being edited. Text=%@&#34;, self.cellIndex, self.fieldBeingEdited.text);
      BOOL resignedFirstResponder;
      ;
      // This method call will log the responder status of this cell and all it is contained within
      //;
      resignedFirstResponder = ;
      NSLog(@&#34;didSelect..: resignFirstResponder on [%p] returned %d&#34;, self.fieldBeingEdited, resignedFirstResponder);
      //;
      if (resignedFirstResponder) {
            self.fieldBeingEdited = NULL;
            self.cellContainingField = NULL;
            self.cellIndex = -1;
      }
    }

    // Enable the textField within the selected cell for in-place editing
    cellDetail.userInteractionEnabled = YES;
    cellDetail.enabled = YES;
    BOOL becameFirstResponder = ;
    NSLog(@&#34;didSelectRow..: becomeFirstResponder returned %d&#34;, becameFirstResponder);
    if ( becameFirstResponder ) {
      // Update all the references and indexes for the cell and textField being edited.
      self.fieldBeingEdited = cellDetail;
      self.cellContainingField = cell;
      self.cellIndex = rowNumber;
    }

    NSLog(@&#34;didSelectRow.. exit; textFieldBeingEdited.text=%@, cellIndex=%d&#34;, self.fieldBeingEdited.text, self.cellIndex);

}

-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField
{
    NSLog(@&#34;textFieldShouldBeginEditing entered&#34;);
    NSLog(@&#34;... returning YES&#34;);
    return YES;
}

-(void) textFieldDidEndEditing:(UITextField *)textField
{
    NSLog(@&#34;textFieldDidEndEditing entered with text: %@, cellIndex=%d&#34;, textField.text, self.cellIndex);
    NSInteger cellIndex = self.cellIndex;

    NSMutableArray * cellData = ];
    ;
    ;
    textField.enabled = NO;

    ;
    if ( ) {
      NSLog(@&#34;EditFlight(466): textFieldDidEndEditing; textField IS STILL the firstresponder!&#34;);
    }
    NSLog(@&#34;textFieldDidEndEditing exit; cellData=%@&#34;, cellData);
}

-(BOOL) textFieldShouldReturn: (UITextField *)textField
{
    NSLog(@&#34;textFieldShouldReturn; textField.text=%@&#34;, textField.text);
    ;
    BOOL resignedFirstResponder = ;
    NSLog(@&#34;textFieldShouldReturn; resignFirstResponder returned %d&#34;,resignedFirstResponder);
    return YES;
}

-(void) showCellResponderStatus:(UITableViewCell*)cell
{
    NSLog(@&#34;showCellResponderStatus entered&#34;);
    if ( ) {
      NSLog(@&#34;cell at [%p] IS first responder&#34;, cell);
    }else{
      NSLog(@&#34;cell at [%p] IS NOT first responder&#34;, cell);
    }
    NSArray * cellSubViews = [ subviews];
    for ( UIView* uiv in cellSubViews ) {
      if ( ) {
            NSLog(@&#34;subview at [%p] is a %@ and IS first responder&#34;, uiv, uiv.class);
      } else {
            NSLog(@&#34;subview at [%p] is a %@ and IS NOT first responder&#34;, uiv, uiv.class);
      }
    }
}

-(void) showViewHierarchy:(UIView*) uiv
{
    NSLog(@&#34;View Hierarchy&#34;);
    while (uiv != NULL) {
      BOOL isfirst = ;
      NSLog(@&#34;view at [%p] is a %@, isFirstResponder=%d&#34;, uiv, uiv.class, isfirst);
      uiv = uiv.superview;
    }
    NSLog(@&#34;view at [%p] is a %@&#34;, uiv, uiv.class);
    NSLog(@&#34;End of view hierarchy&#34;);
}

@end
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>有一个更简单的方法。在 <code>didSelectRowAtIndexPath</code> 中存储对当前单元格的 UITextField 的引用。然后您可以将其设置为第一响应者,处理编辑等。</p>

<p>当您点击一个新单元格以选择它时,代理首先会收到一个 <code>didDeselectRowAtIndexPath</code>。在这里,您可以使用您的 UITextField 引用可以辞职第一响应者,保存任何必要的状态等。然后在新单元格上调用 <code>didDeselectRowAtIndexPath</code> ,您就可以开始了。所以类似于以下内容:</p>

<p><strong>编辑:添加额外代码</strong></p>

<pre><code>// Code additions to Xcode&#39;s Master-Detail application template

// Use dynamic prototypes for table cells, custom cell class follows:

// MyCell.h
// Property is auto-synthesized, so there is nothing to see in MyCell.m

@interface MyCell : UITableViewCell
@property (nonatomic, weak) IBOutlet UITextField *tf;
@end



// MasterViewController.m

@interface MasterViewController () {
NSMutableArray *_objects;
}
@property (nonatomic, weak) UITextField *selectedField;
@end


// this method is called when a cell is DE-selected
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
      ;
      // save state, etc if necessary
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell * cell = (MyCell *);
    self.selectedField = cell.tf; // cell.tf is a UITextField property defined on MyCell
    ;
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在 iOS 中,如何在两个单元格中的文本字段之间切换?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/18581173/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/18581173/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在 iOS 中,如何在两个单元格中的文本字段之间切换?