问题
I am using storyboards and a dynamic UITableView adding my cells like below. I need to know how I can save this text in the UITextField in each cell as well as UISwitch state etc so when I scroll up and down, the data is not lost. Also when the app closes, I need it to show the data entered when reopening. I am pretty new to programming, and this is my first UItableView project. Coding examples would be great, please give as much detail as possible! thank you in advance!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
// Make cell unselectable and set font.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:@"ArialMT" size:13];
if (indexPath.section == 0) {
UITextField* tf = nil;
switch ( indexPath.row ) {
case 0: {
cell.textLabel.text = @"Name" ;
tf = nameFieldTextField = [self makeTextField:self.name placeholder:@"John Appleseed"];
nameFieldTextField.tag = 1;
[cell addSubview:nameFieldTextField];
break ;
}
case 1: {
cell.textLabel.text = @"Address" ;
tf = addressFieldTextField = [self makeTextField:self.address placeholder:@"Street Address"];
addressFieldTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
[cell addSubview:addressFieldTextField];
break ;
}
case 2: {
cell.textLabel.text = @"Email" ;
tf = emailFieldTextField = [self makeTextField:self.email placeholder:@"example@gmail.com"];
emailFieldTextField.keyboardType = UIKeyboardTypeEmailAddress;
[cell addSubview:emailFieldTextField];
break ;
}
case 3: {
cell.textLabel.text = @"Phone" ;
tf = phoneFieldTextField = [self makeTextField:self.phone placeholder:@"xxx-xxx-xxxx"];
phoneFieldTextField.keyboardType = UIKeyboardTypePhonePad;
phoneFieldTextField.tag = 10;
phoneFieldTextField.text = [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES];
[cell addSubview:phoneFieldTextField];
break ;
}
case 4: {
cell.textLabel.text = @"DOB" ;
tf = dateOfBirthTextField = [self makeTextField:self.dateOfBirth placeholder:@"xx/xx/xxxx"];
dateOfBirthTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
[cell addSubview:dateOfBirthTextField];
break ;
}
}
// Textfield dimensions
tf.frame = CGRectMake(120, 12, 170, 30);
// Workaround to dismiss keyboard when Done/Return is tapped
[tf addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];
回答1:
I think you can make a model object for storing the data.
.h file
@interface User : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *address;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString *phone;
@property (nonatomic, copy) NSString *dob;
- (void)save;
+(User *)savedUser;
.m file
#define kName @"Name"
#define kAddress @"Address"
#define kEMail @"EMail"
#define kPhone @"Phone"
#define kDOB @"DOB"
#define kSavedUser @"SavedUser"
@implementation User
- (void)encodeWithCoder:(NSCoder *)encoder{
[encoder encodeObject:self.name forKey:kName];
[encoder encodeObject:self.address forKey:kAddress];
[encoder encodeObject:self.email forKey:kEMail];
[encoder encodeObject:self.phone forKey:kPhone];
[encoder encodeObject:self.dob forKey:kDOB];
}
- (id)initWithCoder:(NSCoder *)decoder{
self = [super init];
if (self) {
self.name = [decoder decodeObjectForKey:kName];
self.address = [decoder decodeObjectForKey:kAddress];
self.email = [decoder decodeObjectForKey:kEMail];
self.phone = [decoder decodeObjectForKey:kPhone];
self.dob = [decoder decodeObjectForKey:kDOB];
}
return self;
}
#pragma mark - Save
- (void)save{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
[defaults setObject:data forKey:kSavedUser];
[defaults synchronize];
}
+(User *)savedUser{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:kSavedUser];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
UITableView DataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier
forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.detailTextField.delegate = self;
[cell.detailTextField setTag:indexPath.row+1];
switch (indexPath.row+1) {
case 1:{
cell.titleLabel.text = @"Name";
cell.detailTextField.text = self.user.name;
break;
}
case 2:{
cell.titleLabel.text = @"Address";
cell.detailTextField.text = self.user.address;
break;
}
case 3:{
cell.titleLabel.text = @"EMail";
cell.detailTextField.text = self.user.email;
break;
}
case 4:{
cell.titleLabel.text = @"Phone";
cell.detailTextField.text = self.user.phone;
break;
}
case 5:{
cell.titleLabel.text = @"D.O.B.";
cell.detailTextField.text = self.user.dob;
break;
}
default:
break;
}
return cell;
}
It's too much to explain. I have attached source code, take a look. Source Code
回答2:
You need to add some sort of persistency. Since you seem to have a very small amount of data, what you need to do is to put your data for your table inside an NSDictionary object by using NSDictionary's writeToFile:atomically: method. You can load the data using NSDictionary's class method dictionaryWithContentsOfFile:, passing as a parameter the place in which you saved your image.
回答3:
First, for saving data from your app you can use Core Data or NSUserDefaults, NSUserDefaults should be use for saving small amount of data, for the rest use Core Data (there are lots of tutorials regarding core data just google it)
But you have to rewrite your cellForRowAtIndexPath method because is wrongly implemented.
First use dequeueReusableCellWithIdentifier to check if there are cells already created (maybe you heard about cell reuse, this is how it's done) because right now you are creating a new cell for each call of the cellForRowAtIndexPath is called (the method it's called every time a cell shows up on the screen).
Second, after dequeueReusableCellWithIdentifier check if the cell that the method returned is nil or not, if it is nil create a new one, if not use the returned cell.
Third, create a custom cell that can have a UITextField or a UISwitch, and in cellForRowAtIndexPath check the text of your UITextField, if is nil the set the placeholder if not leave it as it is this will allow data to be properly displayed when you scroll the table.
Fourth, for UITextFields there are delegate methods that are called when user begins/end editing so you don't need to add [tf addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];, check UITextFieldDelegate protocol (easy google stuff :))
Fifth (the last one i promise) don't use = in on the same line of code, it's ugly and hard to read (tf = nameFieldTextField = [self makeT...)
回答4:
You can save the data in sqlite database.Or you can do take one array in view did load.Initially you will insert null value.when your cell will created once you will replace that null object from that uitableviewcell object.And next time when you will load the cell.You can fetch the data directly from that array.
回答5:
For sample code, take a look at the "Settings" example project in the TLIndexPathTools library on GitHub. It demonstrates how to get user input out of the table. It also shows how you can add dynamic behavior to the table like hiding and showing rows as the inputs change.
It does not show how to persist the values across app sessions. For that look into Core Data or NSUserDefaults as @d4Rk suggested.
回答6:
nsmutablearray *arr=[[nsmutablearray alloc] init];
[arr addobject:[nsnull class]];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:customCellIdentifier];
cell = [[[NSBundle mainBundle]loadNibNamed:@"cell" owner:self options:nil]objectAtIndex:0];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
if (![[saveCellState objectAtIndex:indexPath.row] isKindOfClass:[NSNull class]])
{
cell=(UITableViewCell *)[saveCellState objectAtIndex:indexPath.row];
}
if ([[saveCellState objectAtIndex:indexPath.row] isKindOfClass:[NSNull class]])
{
}
来源:https://stackoverflow.com/questions/16863766/save-uitableview-data