如何管理 UITableView + 动态自定义单元格(UIBUtton + UITextField + UIBUtton)插入?

Posted

技术标签:

【中文标题】如何管理 UITableView + 动态自定义单元格(UIBUtton + UITextField + UIBUtton)插入?【英文标题】:How to manage UITableView + Dynamic Custom Cell(UIBUtton + UITextField + UIBUtton) Insertion? 【发布时间】:2011-06-10 11:19:37 【问题描述】:

我在管理 UITableView 时遇到问题。我在这里发布一个屏幕截图来简要解释这个问题。图 1 显示了首次视图出现时的默认视图。当我点击黄色按钮(黄色按钮在自定义表格部分标题视图中)时,我打开一个带有表格的 UIAlertView,如图 2 所示。然后选择任何选项,我插入一个带有按钮、文本字段和另一个按钮的自定义单元格。我为每个部分都有一个可变数组,所以当我选择一个选项时,我将该字符串添加到相应的部分数组中并重新加载表。参见图像 3。现在,当我在 UITextfields 中输入值时,值会被另一个单元格替换。请参阅下面的两个图像以了解问题。图片 4。此外,当我删除一个单元格并插入一个新单元格时,文本字段会预加载以前的值。

这里是分析问题的.m文件实现代码

#import "contactsViewController.h"
#import "textFieldCell.h"
#import "SBTableAlert.h"
#import "PhoneFieldCell.h"
#import "DHValidation.h"

#define kTextFieldTag 222
#define kTitleButtonTag 111
#define MAX_LENGTH 20
#define charecterLimit 13
#define PHONE_NUMBER @"0123456789+-"

@implementation contactsViewController

@synthesize currentTextField;
@synthesize choiceList;
@synthesize labelHeaders;
@synthesize selectedIndexPath;
@synthesize aTable;
@synthesize customText;
@synthesize currentSelectionType;
@synthesize phoneList;
@synthesize emailList;
@synthesize otherDetailsList;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 
    [super viewDidLoad];
    //Prepare array's for display in table header and in custom alert option table
    [self prepareDataForTable];
    [self initializeProperties];

    //Set selected index to -1 by default
    selectedIndex = -1;


//prepare array's for table
- (void) prepareDataForTable 
    NSArray *temp = [[NSArray alloc] initWithObjects:@"work",@"home",@"mobile",@"custom",nil];
    self.choiceList = temp;
    [temp release];

    NSArray *temp1 = [[NSArray alloc] initWithObjects:@"First Name",@"Last Name",nil];
    self.labelHeaders = temp1;
    [temp1 release];



- (void) initializeProperties 
    //Initialize Mutable array's

    NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:0];
    self.phoneList = temp;
    [temp release];

    NSMutableArray *temp1 = [[NSMutableArray alloc] initWithCapacity:0];
    self.emailList = temp1;
    [temp1 release];

    NSMutableArray *temp2 = [[NSMutableArray alloc] initWithCapacity:0];
    self.otherDetailsList = temp2;
    [temp2 release];    



#pragma mark -

- (IBAction) btnCancelTapped:(id) sender 

    [self dismissModalViewControllerAnimated:YES];


- (IBAction) btnDoneTapped:(id) sender  

    [self.currentTextField resignFirstResponder];

    //TODO: Fetch all the data from all the cells and notify the delegate.
    NSMutableDictionary *allSectionsData = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
    NSMutableDictionary *section1Dictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
    NSMutableDictionary *phoneSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
    NSMutableDictionary *emailSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];
    NSMutableDictionary *otherSectionDictionary = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease];

    //For Section 0
    for (unsigned rowIndex = 0; rowIndex < 2; rowIndex++) 
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
        UITableViewCell *cell = nil;

        cell = (textFieldCell*)[aTable cellForRowAtIndexPath:indexPath];
        UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];

        //TextField validation
        DHValidation *validation = [[DHValidation alloc] init];
        NSString *str =  [txtf.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
        NSString *alertMessage = nil;

        BOOL isvalid = NO;
        if(![validation validateNotEmpty:str])
            alertMessage = @"NameField should not be Empty";
        else 
            isvalid = TRUE;

        if(!isvalid)
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:alertMessage delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
            [alert show];
            [alert  release];
            return ;
        
        [validation release];

        NSString *type = nil;
        NSString *value = nil;

        if(rowIndex == 0)
            type = @"First Name";
        else if(rowIndex == 1)
            type = @"Last Name";
        
        value = txtf.text;
        if(!value) 
            //Do not insert that value in the dictinary
            value = @"";
        else 
            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,@"type",value,@"value",nil];
            [section1Dictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
        
    
    if([section1Dictionary count] > 0) 
        [allSectionsData setObject:section1Dictionary forKey:@"PersonalDetailsSection"];
    



    //For Section 1
    for (unsigned rowIndex = 0; rowIndex < [phoneList count]; rowIndex++) 
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:1];
        UITableViewCell *cell = nil;

        cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];

        UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];

        UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
        NSString *type = nil;
        NSString *value = nil;

        type = [btnTitle currentTitle];
        value = [txtf text];

        if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""] )
            //Do not insert that value in the dictinary
            continue;
        else 
            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,@"type",value,@"value",nil];
            [phoneSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
            //[phoneSectionDictionary setObject:value forKey:type];
        
    
    if([phoneSectionDictionary count] > 0) 
        [allSectionsData setObject:phoneSectionDictionary forKey:@"PhoneSection"];
    

    //For Section 2 
    for (unsigned rowIndex = 0; rowIndex < [emailList count]; rowIndex++) 


        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:2];

        UITableViewCell *cell = nil;

        cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];

        UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];
        UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
        NSString *type = nil;
        NSString *value = nil;


        type = [btnTitle currentTitle];
        value = [txtf text];


        if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""] )
            //Do not insert that value in the dictinary
            continue;
        else 
            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,@"type",value,@"value",nil];
            [emailSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
        
    
    if([emailSectionDictionary count] > 0) 
        [allSectionsData setObject:emailSectionDictionary forKey:@"EmailSection"];
    

    //for Section 3
    for (unsigned rowIndex = 0; rowIndex < [phoneList count]; rowIndex++) 
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:3];
        UITableViewCell *cell = nil;

        cell = (PhoneFieldCell*)[aTable cellForRowAtIndexPath:indexPath];

        UITextField *txtf = (UITextField *)[cell viewWithTag:kTextFieldTag];

        UIButton *btnTitle = (UIButton*)[cell viewWithTag:kTitleButtonTag];
        NSString *type = nil;
        NSString *value = nil;

        type = [btnTitle currentTitle];
        value = [txtf text];

        if(!value || [[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""] )
            //Do not insert that value in the dictinary
            continue;
        else 
            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:type,@"type",value,@"value",nil];
            [otherSectionDictionary setObject:dictionary forKey:[NSNumber numberWithInt:rowIndex]];
            //[phoneSectionDictionary setObject:value forKey:type];
        
    
    if([otherSectionDictionary count] > 0) 
        [allSectionsData setObject:otherSectionDictionary forKey:@"OtherSection"];
    



#pragma mark -
#pragma mark UITableView Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 

    return 4;


// Returns the number of rows in a given section.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

    NSInteger count = 0;
    switch (section) 
        case 0:
            count = 2;
            break;
        case 1://Phone
            count = [phoneList count];
            break;
        case 2://Email
            count = [emailList count];
            break;
        case 3://Other
            count = [otherDetailsList count];
            break;
        default:
            count = 0;
            break;
    
    return count;


// Returns the cell for a given indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    static NSString *CellIdentifier = @"textFieldCustomCell";
    static NSString *PhoneFieldCustomCellIdentifier = @"PhoneFieldCustomCell";
    static NSString *EmailFieldCustomCellIdentifier = @"EmailFieldCustomCell";
    static NSString *OtherDetailsCustomCellIdentifier = @"OtherDetailsCustomCell";

    UITableViewCell *cell = nil;

    switch (indexPath.section) 
        case 0:
                cell = (textFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
                if (cell == nil) 
                    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"textFieldCell" owner:self options:nil];

                    for (id currentObject in topLevelObjects)
                        if ([currentObject isKindOfClass:[textFieldCell class]])
                            cell =  (textFieldCell *) currentObject;
                            break;
                        
                    
                
            

            break;
        case 1:
            cell = (PhoneFieldCell *)[tableView dequeueReusableCellWithIdentifier:PhoneFieldCustomCellIdentifier];
            if (cell == nil) 
                NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"PhoneFieldCell" owner:self options:nil];

                for (id currentObject in topLevelObjects)
                    if ([currentObject isKindOfClass:[PhoneFieldCell class]])
                        cell =  (PhoneFieldCell *) currentObject;
                        ((PhoneFieldCell *)cell).enterText.delegate = self;
                        ((PhoneFieldCell *)cell).enterText.text = nil;
                        break;
                    
                
            
        

            break;
        case 2:
            cell = (EmailFieldCell *)[tableView dequeueReusableCellWithIdentifier:EmailFieldCustomCellIdentifier];
            if (cell == nil) 
                NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"EmailFieldCell" owner:self options:nil];

                for (id currentObject in topLevelObjects)
                    if ([currentObject isKindOfClass:[EmailFieldCell class]])
                        cell =  (EmailFieldCell *) currentObject;
                        ((EmailFieldCell *)cell).enterText.delegate = self;
                        ((EmailFieldCell *)cell).enterText.text = nil;
                        break;
                    
                
            
        

            break;
        case 3:
            cell = (OtherDetailsCell *)[tableView dequeueReusableCellWithIdentifier:OtherDetailsCustomCellIdentifier];
            if (cell == nil) 
                NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"OtherDetailsCell" owner:self options:nil];

                for (id currentObject in topLevelObjects)
                    if ([currentObject isKindOfClass:[OtherDetailsCell class]])
                        cell =  (OtherDetailsCell *) currentObject;
                        ((OtherDetailsCell *)cell).enterText.delegate = self;
                        ((OtherDetailsCell *)cell).enterText.text = nil;
                        break;
                    
                
            
        

            break;
        default:
            break;
    

    //Setup cell data


    switch (indexPath.section) 
        case 0:
                ((textFieldCell*)cell).aTextField.delegate = self;
                if(indexPath.row == 0)
                    ((textFieldCell*)cell).aTextField.placeholder = @"Enter First Name";
                
                if(indexPath.row == 1)
                    ((textFieldCell*)cell).aTextField.placeholder = @"Enter Last Name";
                
                ((textFieldCell*)cell).aLabel.text = [self.labelHeaders objectAtIndex:indexPath.row];           
            
            break;
        case 1:
                NSString *str = [phoneList objectAtIndex:indexPath.row];
                [((PhoneFieldCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
                [((PhoneFieldCell *)cell).changeBtn addTarget:self action:@selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
                ((PhoneFieldCell *)cell).btnDeleteCell.tag = indexPath.row;
                [((PhoneFieldCell *)cell).btnDeleteCell addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
            
            break;
        case 2:
                NSString *str = [emailList objectAtIndex:indexPath.row];
                [((EmailFieldCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
                [((EmailFieldCell *)cell).changeBtn addTarget:self action:@selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
                ((EmailFieldCell *)cell).btnDeleteCell.tag = indexPath.row;
                [((EmailFieldCell *)cell).btnDeleteCell addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
            
            break;
        case 3:
                NSString *str = [otherDetailsList objectAtIndex:indexPath.row];
                [((OtherDetailsCell *)cell).changeBtn setTitle:str forState:UIControlStateNormal];
                [((OtherDetailsCell *)cell).changeBtn addTarget:self action:@selector(changeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
                ((OtherDetailsCell *)cell).btnDeleteCell.tag = indexPath.row;
                [((OtherDetailsCell *)cell).btnDeleteCell addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
            
            break;

        default:
            break;
    
    return cell;


- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
    return 30;

- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section 
    if (section == 0) 
        return nil;
    
    return [self headerViewForSection:section];



// Handle row selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath




- (UIView*) headerViewForSection:(NSInteger)section 

    CGRect lblTitleFrame = CGRectMake(15, 0, 200, 20);
    CGRect btnFrame = CGRectMake(280.0, 0.0, 30.0, 30.0);
    CGRect headerViewFrame = CGRectMake(0,0, 40, 30);

    NSString *lblTitleText = nil;

    switch (section) 
        case 1://phone
            lblTitleText = @"Phone";
            break;
        case 2://email
            lblTitleText = @"Email";

            break;
        case 3://other details
            lblTitleText = @"Other";

            break;
        default:
            break;
    

    //Create a header view with a label and a button

    UIView *headerView = [[[UIView alloc] initWithFrame:headerViewFrame] autorelease];

    UILabel *titleForTable = [[UILabel alloc]initWithFrame:lblTitleFrame];
    titleForTable.text = lblTitleText;
    titleForTable.backgroundColor = [UIColor clearColor];
    titleForTable.textColor = [UIColor whiteColor];
    titleForTable.shadowColor = [UIColor whiteColor];
    [headerView addSubview:titleForTable];
    [titleForTable release];

    UIButton *phoneButton = [[UIButton alloc] initWithFrame:btnFrame];
    phoneButton.alpha = 0.7;
    phoneButton.tag = section;
    [phoneButton setImage:[UIImage imageNamed:@"Yellow.png"] forState: UIControlStateNormal];

    [phoneButton addTarget: self action: @selector(headerTapped:) forControlEvents: UIControlEventTouchUpInside];

    [headerView addSubview: phoneButton];
    [phoneButton release];

    return headerView;  

#pragma mark -
#pragma mark UITextField Delegate
- (void)textFieldDidBeginEditing:(UITextField *)textField 
    self.currentTextField = textField;



- (BOOL)textFieldShouldReturn:(UITextField *)textField 
    [textField resignFirstResponder];
    return YES;

//textfield charecters range
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

    if (textField.text.length >= MAX_LENGTH && range.length == 0)
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"You reached maximum limit - 20" 
                                                       delegate:self 
                                              cancelButtonTitle:@"Ok" 
                                              otherButtonTitles:nil];
        [alert show];
        [alert  release];
        return NO; // return NO to not change text
    
    else 
        return YES;
    


#pragma mark -
- (void)deleteButtonTapped:(id)sender

    if([self.currentTextField isFirstResponder]) 
        [self.currentTextField resignFirstResponder];
    


    NSLog(@"Button Pressed");

    UIButton *btnDelete = (UIButton*)sender;
    id cell = [[btnDelete superview] superview];

    if([cell isKindOfClass:[PhoneFieldCell class]]) 
        cell = (PhoneFieldCell*)cell;
    
    if([cell isKindOfClass:[EmailFieldCell class]]) 
        cell = (EmailFieldCell*)cell;
    
    if([cell isKindOfClass:[OtherDetailsCell class]]) 
        cell = (OtherDetailsCell*)cell;
    


    NSIndexPath *indexPath = [aTable indexPathForCell:cell];
    NSLog(@"Section is %d and row is %d",indexPath.section,indexPath.row);

    switch (indexPath.section) 
        case 1:
            [self.phoneList removeObjectAtIndex:[btnDelete tag]];
            [aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case 2:
            [self.emailList removeObjectAtIndex:[btnDelete tag]];
            [aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case 3:
            [self.otherDetailsList removeObjectAtIndex:[btnDelete tag]];
            [aTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        default:
            break;
    
    [aTable reloadData];


- (void)changeButtonTapped:(id)sender

    if([self.currentTextField isFirstResponder]) 
        [self.currentTextField resignFirstResponder];
    

    UIButton *btnDelete = (UIButton*)sender;
    id cell = (PhoneFieldCell*)[[btnDelete superview] superview];

    if([cell isKindOfClass:[PhoneFieldCell class]]) 
        cell = (PhoneFieldCell*)cell;
    
    if([cell isKindOfClass:[EmailFieldCell class]]) 
        cell = (EmailFieldCell*)cell;
    
    if([cell isKindOfClass:[OtherDetailsCell class]]) 
        cell = (OtherDetailsCell*)cell;
    

    self.selectedIndexPath = [aTable indexPathForCell:cell];
    shouldModify = YES;

    NSLog(@"Section is %d and row is %d",self.selectedIndexPath.section,self.selectedIndexPath.row);


    SBTableAlert *alert = nil;      
     alert  = [[[SBTableAlert alloc] initWithTitle:@"Options" cancelButtonTitle:@"Cancel" messageFormat:@"Select your option!"] autorelease];
    [alert setType:SBTableAlertTypeSingleSelect];
    [alert.view addButtonWithTitle:@"OK"];

    [alert setDelegate:self];
    [alert setDataSource:self];
    [alert show];




- (void)headerTapped:(id)sender 

    if([self.currentTextField isFirstResponder]) 
        [self.currentTextField resignFirstResponder];
    

    UIButton *tappedButton = (UIButton*)sender;

    //set current selection according to section
    switch ([tappedButton tag]) 
        case 1://Phone
            self.currentSelectionType = SELECTIONTYPE_PHONE;
            break;
        case 2://Email
            self.currentSelectionType = SELECTIONTYPE_EMAIL;
            break;
        case 3://Other details
            self.currentSelectionType = SELECTIONTYPE_OTHER;
            break;
        default:
            break;
    

    SBTableAlert *alert;        
    alert   = [[[SBTableAlert alloc] initWithTitle:@"Options" cancelButtonTitle:@"Cancel" messageFormat:@"Select your option!"] autorelease];
    [alert setType:SBTableAlertTypeSingleSelect];
    [alert.view addButtonWithTitle:@"OK"];

    [alert setDelegate:self];
    [alert setDataSource:self];

    [alert show];





#pragma mark - SBTableAlertDataSource

- (UITableViewCell *)tableAlert:(SBTableAlert *)tableAlert cellForRow:(NSInteger)row 
    UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil] autorelease];

    [cell.textLabel setText:[self.choiceList objectAtIndex:row]];
    if(row == selectedIndex)
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else 
        cell.accessoryType == UITableViewCellAccessoryNone;
    
    return cell;


- (NSInteger)numberOfRowsInTableAlert:(SBTableAlert *)tableAlert 
    if (tableAlert.type == SBTableAlertTypeSingleSelect)
        return [self.choiceList count];
    else
        return 4;


#pragma mark - SBTableAlertDelegate

- (void)tableAlert:(SBTableAlert *)tableAlert didSelectRow:(NSInteger)row 
    if (tableAlert.type == SBTableAlertTypeMultipleSelct) 
        UITableViewCell *cell = [tableAlert.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0]];
        if (cell.accessoryType == UITableViewCellAccessoryNone)
            [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
        else
            [cell setAccessoryType:UITableViewCellAccessoryNone];

        [tableAlert.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:YES];
    
    else if (tableAlert.type == SBTableAlertTypeSingleSelect) 
        selectedIndex = row;
        [tableAlert.tableView reloadData];
        [tableAlert.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:YES];
    


- (void)tableAlert:(SBTableAlert *)tableAlert didDismissWithButtonIndex:(NSInteger)buttonIndex 
    if(buttonIndex == 1)
    if(selectedIndex == -1)
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Select at least one choice" message:nil 
                                                delegate:nil 
                                       cancelButtonTitle:@"Ok" 
                                       otherButtonTitles:nil];
        [alert show];
        [alert release];
    

    else if(cellSelected ==  FALSE)
        if(selectedIndex  == 3)
            UIAlertView *customAlert = [[UIAlertView alloc] initWithTitle:@"Enter Custom Message" message:@"\n\n" 
                                                                 delegate:self 
                                                        cancelButtonTitle:@"Cancel" 
                                                        otherButtonTitles:@"Ok",nil];
            customAlert.tag = 99;

            CGAffineTransform myTransForm = CGAffineTransformMakeTranslation(0,0);
            UITextField *temp = [[UITextField alloc] initWithFrame:CGRectMake(15, 50, 255, 30)];
            self.customText = temp;
            [temp release];
            self.customText.backgroundColor = [UIColor whiteColor];
            self.customText.placeholder = @"Enter Custom Text";
            self.customText.clearButtonMode = UITextFieldViewModeWhileEditing;
            self.customText.layer.cornerRadius = 5;
            [customAlert addSubview:self.customText];
            [customAlert setTransform:myTransForm];

            [customAlert show];
            [customAlert release];

        else 
            UITableViewCell *cell = [tableAlert.tableView cellForRowAtIndexPath:[ NSIndexPath indexPathForRow:selectedIndex inSection:0]];
            NSString *val = cell.textLabel.text;
            if(!shouldModify) 
                switch (self.currentSelectionType) 
                    case SELECTIONTYPE_PHONE:
                        [phoneList addObject:val];
                        break;
                    case SELECTIONTYPE_EMAIL:
                        [emailList addObject:val];
                        break;
                    case SELECTIONTYPE_OTHER:
                        [otherDetailsList addObject:val];
                        break;
                    default:
                        break;
                   
            
            else 
                switch (self.selectedIndexPath.section) 
                    case 1:
                        [phoneList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
                        break;
                    case 2:
                        [emailList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
                        break;
                    case 3:
                        [otherDetailsList replaceObjectAtIndex:self.selectedIndexPath.row withObject:val];
                        break;
                    default:
                        break;
                   
                shouldModify = NO;
            

        

    
    if(self.currentSelectionType != SELECTIONTYPE_UNKNOWN || self.selectedIndexPath.section > 0)
        [aTable reloadData];
    selectedIndex = -1;
    [tableAlert release];
    



- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 

    if(alertView.tag == 99 && buttonIndex == 1)

            NSString *val = [self.customText text];
        if(!val || [[val stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""])
                //show error alert here and return from here
                UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                     message:@"Please fill a value for custom text"
                                                                    delegate:nil
                                                           cancelButtonTitle:@"OK"
                                                           otherButtonTitles:nil];
                [errorAlert show];
                [errorAlert release];
                return;
            
            switch (self.currentSelectionType) 
                case SELECTIONTYPE_PHONE:
                    [phoneList addObject:val];
                    [aTable reloadData];
                    break;
                case SELECTIONTYPE_EMAIL:
                    [emailList addObject:val];
                    [aTable reloadData];
                    break;
                case SELECTIONTYPE_OTHER:
                    [otherDetailsList addObject:val];
                    [aTable reloadData];
                    break;
                default:
                    break;
                       
        


#pragma mark -

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);

*/

- (void)didReceiveMemoryWarning 
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.


- (void)viewDidUnload 
    self.currentTextField = nil;

    self.choiceList = nil;
    self.labelHeaders = nil;

    self.selectedIndexPath = nil;
    self.aTable = nil;
    self.customText = nil;
    self.phoneList = nil;
    self.emailList = nil;
    self.otherDetailsList = nil;
    self.customText = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;


- (void)dealloc 
    [phoneList release];
    [emailList release];
    [otherDetailsList release];
    [customText release];
    [customText release];
    [aTable release];
    [selectedIndexPath release];
    [choiceList release];
    [labelHeaders release];

    [currentTextField release];

    [super dealloc];


@end

【问题讨论】:

【参考方案1】:

这是你的答案http://www.icodeblog.com/2011/01/04/elctextfieldcell-a-useful-tableviewcell-for-forms/

你也可以根据你的应用需要手动做一些自定义

 - (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath

     [tableView reloadData];

  

【讨论】:

我不想使用其他类。我想创建我自己的。问题只是文本字段值的可重复性,当我删除一行并插入新的文本字段时,预填充了以前的值 didEndEditingRowAtIndexPath 在这里我们可以得到编辑的回调,所以在这里我们可以重新加载数据,这将是新的。你的问题是重用单元格 请来iphone/ipad房间

以上是关于如何管理 UITableView + 动态自定义单元格(UIBUtton + UITextField + UIBUtton)插入?的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如何在动态 UITableView 的自定义单元格中获取滑块的值?

如何更新动态生成的故事板中的自定义特定 UITableview 单元格?

UITableView 自定义 Cells,滚动和内存管理

如何使用子视图的延迟/动态加载实现自定义 UIView,类似于 UITableView

tableView:viewForHeaderInSection: 如何准确工作以及如何动态自定义此视图

具有静态单元的 UItableView 包含 2 个 UItableview,每个都有具有动态高度的自定义单元