UITableView reloadData automatically calls resignFirstResponder

后端 未结 13 1397
天命终不由人
天命终不由人 2020-12-02 22:44

I have this UITableView with custom cells that can get only predefined values, therefore I use a UIPickerView as their inputView. All is jolly good until I edit a field and

相关标签:
13条回答
  • 2020-12-02 23:05

    You can follow this approach, not the best, but it works:

    // pass the responder to a temporary (hidden) textField
    [_tmpTextField becomeFirstResponder];
    
    // reload data
    [_tableView reloadData];
    
    // reloadData is definitely async... 
    // so pass the responder back in a timed op
    double delayInSeconds = 0.1;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [_textField becomeFirstResponder];
    });
    
    0 讨论(0)
  • 2020-12-02 23:12

    As mentioned by @Eiko, this works for me!

    Update the cell in UIPickerViewDelegate's pickerView:didSelectRow:inComponent: method:

    - (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
      TableViewCell *cell = (TableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:pickerView.tag inSection:0]];
    
      /*
      Update your cell here. 
      */
    
      // Reload TableViewCell will resign the PickerView, so we need to focus it back.  
      [self.tableView reloadData];
      NSIndexPath* indexPath = [self.tableView indexPathForCell:cell];
      NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
      [self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
      [cell.textField becomeFirstResponder];
    }
    
    0 讨论(0)
  • 2020-12-02 23:15

    If you are facing this issue with a search bar, the following did it for me in iOS 6:

    • Instantiate a UISearchBar and add it as a subview to your UITableView at the top.
    • Create a dummy first cell in your UITableView so that the search bar only blocks this dummy cell and not your actual cell with data.
    0 讨论(0)
  • 2020-12-02 23:15

    I use beginUpdate and endUpdate After end update, get the cell contains the textfield already has focus then make it first responder

        self.tableView.beginUpdates()
        self.tableView.reloadRows(at: [indexPath], with: .automatic)
        self.tableView.endUpdates()
        let newCell = self.tableView.cellForRow(at: indexPath)
        newCell.textField.becomeFirstResponder()
    
    0 讨论(0)
  • Swift solution:

    we can override default canResignFirstResponder by subclassing UITextfiled

    class CustomField: UITextField{
        var canResign:Bool = false
        override var canResignFirstResponder: Bool{
            return canResign
        }  
    }
    

    all you need to set canResign variable before and after reload statement.

    cell.offerInputTextField.canResign = false
    tableView.reloadData()
    cell.offerInputTextField.canResign = true
    

    don't forget to assign the custom class text field as CustomField.

    0 讨论(0)
  • 2020-12-02 23:18

    I met the same problem, none of the answers above worked perfectly (I see the keyboard bouncing up and down, etc.).
    Following this SO post I fixed the issue by calling

    [tableView beginUpdates];
    [tableView endUpdates]; 
    

    this worked for me, table rows get updates and even expand/shrink (if you are changing rows height dynamically) with a nice animation, all without resigning first responder or even starting keyboard dismiss.
    This will not scroll your table view to fit any expanded row, so I put the snippet above in dedicated method, f.e.:

    - (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath 
    {  
        [tableView beginUpdates];
        [tableView endUpdates]; 
    
        [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
    
    0 讨论(0)
提交回复
热议问题