可以使用文本字段扩展的Tableview单元格会导致文本字段跳转

时间:2020-12-13 10:44:01

So i have been trying for a little while now to create a table view with expandable sections and one non expandable section. One of the expandable sections should have 3 text fields inside them in which you can edit the test inside the text field. I was able to get that working bt the moment you collapse the section and expand it again the textfield suddenly duplicates itself above and sometimes swaps itself out with the above cell. Ihavent been able to figure out why or how to make it not do that. The idea is when the user enters text in the field and selects enter the text is stored into an array.

所以我现在尝试了一段时间来创建一个带有可扩展部分和一个不可扩展部分的表视图。其中一个可扩展部分应在其中包含3个文本字段,您可以在其中编辑文本字段内的测试。当你折叠部分并再次扩展它时,我能够得到那个工作,文本字段突然在上面重复,有时与上面的单元格交换。 Ihavent能够弄清楚为什么或如何让它不那样做。这个想法是当用户在字段中输入文本并选择输入时将文本存储到数组中。

the code:

    - (void)viewDidLoad{
    [super viewDidLoad];

    if (!expandedSections){
        expandedSections = [[NSMutableIndexSet alloc] init];
    }
    manualSensorName = [[NSMutableArray alloc]initWithObjects: @"Sensor",@"",@"2",@"T", nil];
}

- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Expanding

- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section{
    if (section>0) return YES;

    return NO;
}


#pragma mark - Table view data source

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    if ([self tableView:tableView canCollapseSection:section])
    {
        if ([expandedSections containsIndex:section])
        {
            return 5; // return rows when expanded
        }

        return 1; // only top row showing
    }

    // Return the number of rows in the section.
    return 1;
}

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...

    if ([self tableView:tableView canCollapseSection:indexPath.section]){
        if (!indexPath.row){
            // first row
            cell.textLabel.text = @"Expandable"; // only top row showing

            if ([expandedSections containsIndex:indexPath.section])
            {
                UIImageView *arrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrowUP.png"]];
                cell.accessoryView = arrow;
            }
            else
            {
                UIImageView *arrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrowDOWN.png"]];
                cell.accessoryView = arrow;
            }
        }
        else {
            if (indexPath.row == 1){
                NSString *flightNumText = [manualSensorName objectAtIndex:indexPath.row];
                cell.textLabel.text = flightNumText;
            }
            else if (indexPath.row == 2){
                txtManualSensor = [[UITextField alloc] initWithFrame:CGRectMake(180, 5, 120, 30)];
                txtManualSensor.placeholder = @"Select";
                txtManualSensor.delegate = self;
                txtManualSensor.autocorrectionType = UITextAutocorrectionTypeNo;
                txtManualSensor.backgroundColor = [UIColor whiteColor];
                [txtManualSensor setBorderStyle:UITextBorderStyleBezel];
                [txtManualSensor setTextAlignment:NSTextAlignmentCenter];
                [txtManualSensor setReturnKeyType:UIReturnKeyDone];
//                UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(180, 5, 120, 30)];
//                playerTextField.adjustsFontSizeToFitWidth = YES;
//                playerTextField.textColor = [UIColor blackColor];
//                playerTextField.placeholder = @"SAMPLE";
//                playerTextField.tag = 200;
//                playerTextField.delegate = self;
//                [cell.contentView addSubview:playerTextField];
                cell.textLabel.text = @"Sensor Name";
                [cell addSubview:txtManualSensor];
            }
            else if (indexPath.row == 3){
                cell.textLabel.text = @"Some Detail";
                cell.accessoryView = nil;
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
            }

        }
    }
    else {
        cell.accessoryView = nil;
        cell.textLabel.text = @"Normal Cell";

    }

    return cell;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    [manualSensorName replaceObjectAtIndex:2 withObject:textField.text];
    return YES;
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{

    [textField resignFirstResponder];
    return YES;
}

// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}


#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([self tableView:tableView canCollapseSection:indexPath.section]){
        if (!indexPath.row){
            [tableView beginUpdates];

            // only first row toggles exapand/collapse
            [tableView deselectRowAtIndexPath:indexPath animated:YES];

            NSInteger section = indexPath.section;
            BOOL currentlyExpanded = [expandedSections containsIndex:section];
            NSInteger rows;

            NSMutableArray *tmpArray = [NSMutableArray array];

            if (currentlyExpanded) {
                rows = [self tableView:tableView numberOfRowsInSection:section];
                [expandedSections removeIndex:section];
            }
            else {
                [expandedSections addIndex:section];
                rows = [self tableView:tableView numberOfRowsInSection:section];
            }

            for (int i=1; i<rows; i++) {
                NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i inSection:section];
                [tmpArray addObject:tmpIndexPath];
            }

            UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
            if (currentlyExpanded) {
                UIImageView *arrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrowDOWN.png"]];
                [tableView deleteRowsAtIndexPaths:tmpArray
                                 withRowAnimation:UITableViewRowAnimationFade];
                cell.accessoryView = arrow;
            }
            else {
                UIImageView *arrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrowUP.png"]];
                [tableView insertRowsAtIndexPaths:tmpArray
                                 withRowAnimation:UITableViewRowAnimationFade];
                cell.accessoryView =  arrow;
            }
            NSLog(@"tableview row is %ld in section %ld",(long)indexPath.row,(long)indexPath.section);
            [tableView endUpdates];
        }
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
        NSLog(@"selected row is %ld in section %ld",(long)indexPath.row,(long)indexPath.section);
        if (indexPath.row == 1) {
            // update text fields in cell table view
        }
    }
}

1 个解决方案

#1


0  

It may be as simple as replacing UITableViewRowAnimationTop by UITableViewRowAnimationFade:
When changing indexes in didSelectRowAtIndexPath, UITableViewCells change physical location (remember that the UITableView is a UIScrollView), and the scroller can't keep track of what your intent is.

它可能就像用UITableViewRowAnimationFade替换UITableViewRowAnimationTop一样简单:在更改didSelectRowAtIndexPath中的索引时,UITableViewCells会更改物理位置(请记住UITableView是UIScrollView),并且滚动条无法跟踪您的意图。

UITableViewRowAnimationTop attempts to adjust the scrolling location, but fails.

UITableViewRowAnimationTop尝试调整滚动位置,但失败。


Other design considerations:

其他设计考虑:

  • Do not mix the model (the array of data to be displayed) with your view model (the UI displaying the model). In didSelectRowAtIndexPath, you should first re-order your model, then apply it to the cells

    不要将模型(要显示的数据数组)与视图模型(显示模型的UI)混合。在didSelectRowAtIndexPath中,您应首先重新排序模型,然后将其应用于单元格

  • Consider not changing indexes on the fly: you may prefer a model that actually reflects the view structure, i.e. a tree.

    考虑不要动态更改索引:您可能更喜欢实际反映视图结构的模型,即树。

  • Have you noticed you are not respecting - (void)tableView:(UITableView *)tableView and sometimes using self tableView:tableView or self.customTableView in the same method? You should use the tableView passed to you.

    您是否注意到您不尊重 - (void)tableView:(UITableView *)tableView并且有时在同一方法中使用self tableView:tableView或self.customTableView?你应该使用传递给你的tableView。

#1


0  

It may be as simple as replacing UITableViewRowAnimationTop by UITableViewRowAnimationFade:
When changing indexes in didSelectRowAtIndexPath, UITableViewCells change physical location (remember that the UITableView is a UIScrollView), and the scroller can't keep track of what your intent is.

它可能就像用UITableViewRowAnimationFade替换UITableViewRowAnimationTop一样简单:在更改didSelectRowAtIndexPath中的索引时,UITableViewCells会更改物理位置(请记住UITableView是UIScrollView),并且滚动条无法跟踪您的意图。

UITableViewRowAnimationTop attempts to adjust the scrolling location, but fails.

UITableViewRowAnimationTop尝试调整滚动位置,但失败。


Other design considerations:

其他设计考虑:

  • Do not mix the model (the array of data to be displayed) with your view model (the UI displaying the model). In didSelectRowAtIndexPath, you should first re-order your model, then apply it to the cells

    不要将模型(要显示的数据数组)与视图模型(显示模型的UI)混合。在didSelectRowAtIndexPath中,您应首先重新排序模型,然后将其应用于单元格

  • Consider not changing indexes on the fly: you may prefer a model that actually reflects the view structure, i.e. a tree.

    考虑不要动态更改索引:您可能更喜欢实际反映视图结构的模型,即树。

  • Have you noticed you are not respecting - (void)tableView:(UITableView *)tableView and sometimes using self tableView:tableView or self.customTableView in the same method? You should use the tableView passed to you.

    您是否注意到您不尊重 - (void)tableView:(UITableView *)tableView并且有时在同一方法中使用self tableView:tableView或self.customTableView?你应该使用传递给你的tableView。