简体   繁体   中英

Store table view data in array on button click - Objective c

I have a UITableView with each cell having text fields. I want to get the text written in those text field in an NSMutableArray

Currently am doing this on button click -

- (void)viewDidLoad {
    [super viewDidLoad];
   _optionTextArray = [[NSMutableArray alloc] init];

}

- (IBAction)saveClicked:(UIButton *)sender {

    editVotingOptionCell *cell = [_tableView dequeueReusableCellWithIdentifier:@"cell"];

    for (int i=0; i<_optionArray.count; i++) {
        [_optionTextArray addObject:cell.tfOption.text];
    }
}

But every time empty string is getting stored.

@interface MyCell: UITableViewCell {
    @property(strong) UITextField *textField;
}

Suppose you have a cell with class MyCell when your button is tap first get the number of rows in section. Let you have a default section which is 0 so get the number of rows for section zero after this iterate through a loop and get cell at every indexPath and get the text from that indexPath and check whether text is empty or not and finally insert it into an Array. Bellow is the sample code of button click.

    NSInteger numberOfRows = [self.tableView numberOfRowsInSection:0]
    NSMutableArray *allTexts = [NSMutableArray new];
    for (NSInteger i = 0; i< numberOfRows; i++) {
         NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
         MyCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (cell.textField.text != nil) {
            [allText addObject:cell.textField.text];
        }

}

You can try

(IBAction)saveClicked:(UIButton *)sender {

     for (int i=0; i<_optionArray.count; i++) {

        editVotingOptionCell *cell = [_tableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:i inSection:0]];
        if (cell != nil) {
          [_optionTextArray addObject:cell.tfOption.text];
        }
        else {
          NSLog(@"nil cell")
        }

    }
}

//

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { 
   editVotingOptionCell*cell = ///
   cell.tfOption.delegate = self;
   cell.tfOption.tag = indexPath.row;
   return cell;
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
   _optionTextArray[textField.tag] = textField.text 
}

//

@interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate>

Note: pre-init the array _optionTextArray with default values

If all cells are visible, as you said, you can do it like here:

- (IBAction)saveClicked:(UIButton *)sender {
    for (int i=0; i < _tableView.visibleCells.count; i++) {
       editVotingOptionCell *cell = self.tableView.visibleCells[i];
       [_optionTextArray addObject: cell.tfOption.text];
    }
}

UPDATE:

This method usable only if all your cells visible.

Because of reusing you can't get textField in the binding to concrete cell. Table view reuse cells.

So advice that you can see below that with cellForRowAtIndexPath:indexPath is not good idea because of table view policy.

If you want to get all texts from cells you should save it in array in other place, not in table view cells. For example, you can save text from text field in UITextFieldDelegate method after text field update.

I think it's better to get data from the tableView's dataSource array rather than from cells.

So everytime textField's text changed you shoule store it's value,I had written a demo for you:

This is MyCell.h code:

#import <UIKit/UIKit.h>

typedef void(^TextFieldValueChangedBlock)(NSString *text);

@interface MyCell : UITableViewCell

@property (nonatomic, copy) TextFieldValueChangedBlock textFieldValueChangedBlock;

@property (nonatomic, copy) NSString *textFieldValue;

@end

This is MyCell.m code:

#import "MyCell.h"

@interface MyCell ()

@property (nonatomic, strong) UITextField *myTextField;

@end

@implementation MyCell 

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.myTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
        [self.contentView addSubview:self.myTextField];
        [self.myTextField addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged];
    }
    return self;
}

- (void)textFieldChanged:(UITextField *)textField {
    if (self.textFieldValueChangedBlock) {
        self.textFieldValueChangedBlock(textField.text);
    }
}

- (void)setTextFieldValue:(NSString *)textFieldValue {
    self.myTextField.text = textFieldValue;
}

@end

At last this is ViewController.m code:

#import "ViewController.h"
#import "MyCell.h"

@interface ViewController () <UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataArray;

@property (nonatomic, strong) NSMutableArray *stringArray;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.dataArray = [NSMutableArray array];
    for (int i = 0; i < 100; i++) {
        [self.dataArray addObject:@"text"];
    }

    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.tableView];
    self.tableView.dataSource = self;
}

- (void)saveClicked:(UIButton *)sender {
    self.stringArray = self.dataArray.mutableCopy;
}

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellReuseID = @"cell";
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseID];
    if (!cell) {
        cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseID];
    }
    cell.textFieldValue = self.dataArray[indexPath.row];
    // textField value change,store value
    __weak typeof(self) weakSelf= self;
    cell.textFieldValueChangedBlock = ^(NSString *text) {
        __strong typeof(self) strongSelf = weakSelf;
        [strongSelf.dataArray replaceObjectAtIndex:indexPath.row withObject:text];
    };
    return cell;
}

@end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM