W tej chwili waliłem w to przez dzień lub dwa i nie mogę sprawić, żeby działało tak, jak chcę. Próbuję naśladować stronę edycji kontaktu z książką adresową (wiem, że została wcześniej zapytana).edytowalne UITableView, UITextField w komórce, przechowujące dane po naciśnięciu
Mam niestandardową UITableViewCell, która zawiera UITextField, który znajduje się w tym samym miejscu, co etykieta tekstu szczegółowego, a po naciśnięciu przycisku edycji ukrywają się i pokazują, że wyświetlają poprawne elementy.
Używam UITextFieldDelegate do przechowywania informacji wpisanych w polach tekstowych do słownika, dzięki czemu można zapisać je do tablicy widoku i mojego podstawowego modelu danych, gdy użytkownik kliknie "wykonane".
Teraz problem: Jeśli tekst zostanie wprowadzony do pola, żadne inne pole/komórka nie zostanie wybrane, a naciśnięcie zostanie wykonane, zmieniona informacja zostanie zignorowana, nigdy nie zostanie zapisana w słowniku.
Mój kod teraz wypisuje zawartość słownika tylko do NSLog po naciśnięciu, ponieważ nie widzę potrzeby aktualizacji komórki, dopóki stan słownika nie będzie poprawny.
Wymieniłem wszystkie metody UITextFieldDelegate z logami, kiedy każda rzecz zostanie uruchomiona, aby spróbować śledzić, jak coś płynie, ale nie pomogło mi obejść tego konkretnego problemu.
Oto kod:
EditableCellStyle2.h
@interface EditableCellStyle2 : UITableViewCell {
CGRect editRect;
UITextField *editField;
}
@property (nonatomic, readonly, retain) UITextField *editField;
@end
EditibleCellStyle2.m
#import "EditableCellStyle2.h"
@implementation EditableCellStyle2
@synthesize editField;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code.
editRect = CGRectMake(83, 12, self.contentView.bounds.size.width-83, 19);
editField = [[UITextField alloc] initWithFrame:editRect];
editField.font = [UIFont boldSystemFontOfSize:15];
editField.textAlignment = UITextAlignmentLeft;
editField.textColor = [UIColor blackColor];
editField.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[self.contentView addSubview:editField];
self.editField.enabled = NO;
self.editField.hidden = YES;
}
return self;
}
-(void)layoutSubviews
{
[super layoutSubviews]; // layouts the cell as UITableViewCellStyleValue2 would normally look like
editRect = CGRectMake(self.detailTextLabel.frame.origin.x, self.detailTextLabel.frame.origin.y, self.contentView.frame.size.width-self.detailTextLabel.frame.origin.x, self.detailTextLabel.frame.size.height);
editField.frame = editRect;
}
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
if (state & UITableViewCellStateEditingMask) {
self.detailTextLabel.hidden = YES;
self.editField.enabled = YES;
self.editField.hidden = NO;
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state {
[super didTransitionToState:state];
if (!(state & UITableViewCellStateEditingMask)) {
self.editField.enabled = NO;
self.editField.hidden = YES;
self.detailTextLabel.hidden = NO;
self.editField.text = self.detailTextLabel.text;
}
}
- (void)dealloc {
[editField release];
[super dealloc];
}
@end
DetailViewController.h
#import <UIKit/UIKit.h>
#import "Entry.h"
#import "Station.h"
#import "EditableCellStyle2.h"
@interface EntryDetailViewController : UITableViewController <UITextFieldDelegate> {
NSManagedObjectContext *currentContext;
Entry *passedEntry;
NSMutableArray *sectionsArray;
NSMutableDictionary *editModeDict;
}
@property (nonatomic, retain) NSManagedObjectContext *currentContext;
@property (nonatomic, retain) Entry *passedEntry;
-(void)editPressed;
-(void)donePressed;
-(void)cancelPressed;
@end
DetailViewController.m
-(void)editPressed
{
[self setEditing:YES animated:YES];
}
-(void)donePressed
{
[self setEditing:NO animated:YES];
NSLog(@"%@", editModeDict);
[self.tableView reloadData];
}
-(void)cancelPressed
{
[self setEditing:NO animated:YES];
[editModeDict removeAllObjects];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return [sectionsArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSArray *thisSection = [sectionsArray objectAtIndex:section];
return [thisSection count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
EditableCellStyle2 *cell = (EditableCellStyle2 *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[EditableCellStyle2 alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSArray *array = [sectionsArray objectAtIndex:indexPath.section];
NSDictionary *dictionary = [array objectAtIndex:indexPath.row];
id key = [[dictionary allKeys] objectAtIndex:0];
cell.textLabel.text = [NSString stringWithFormat:@"%@", key];
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", [dictionary objectForKey:key]];
// Set the edit field to match the detail label on creation so it doesn't look odd on first edit (slide down)
cell.editField.text = cell.detailTextLabel.text;
// Set the edit placeholder to match the key
cell.editField.placeholder = [NSString stringWithFormat:@"%@", key];
// Set the tag for the edit field for the cell based on what cell is being created
// We will use this in the UITextField delegate to store the data in a dictionary
if ([cell.textLabel.text isEqualToString:@"Odometer"])
cell.editField.tag = kOdometer;
else if ([cell.textLabel.text isEqualToString:@"Quantity"])
cell.editField.tag = kQuantity;
else if ([cell.textLabel.text isEqualToString:@"PricePer"])
cell.editField.tag = kPricePer;
else if ([cell.textLabel.text isEqualToString:@"PriceTotal"])
cell.editField.tag = kPriceTotal;
else if ([cell.textLabel.text isEqualToString:@"Name"])
cell.editField.tag = kStationName;
else if ([cell.textLabel.text isEqualToString:@"Address"])
cell.editField.tag = kStationAddress;
else if ([cell.textLabel.text isEqualToString:@"City"])
cell.editField.tag = kStationCity;
else if ([cell.textLabel.text isEqualToString:@"State"])
cell.editField.tag = kStationState;
else if ([cell.textLabel.text isEqualToString:@"Zip"])
cell.editField.tag = kStationZip;
else if ([cell.textLabel.text isEqualToString:@"Notes"])
cell.editField.tag = kNotes;
// Set the delegate of the edit field to self
[cell.editField setDelegate:self];
return cell;
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
// When we go into editing mode, hide the back button, when we come out of editing mode, show it.
self.navigationItem.hidesBackButton = editing;
// Replace the back button with a cancel button that is only active while in edit mode
if (editing) {
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelPressed)];
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
// clear the right bar button (edit)
self.navigationItem.rightBarButtonItem = nil;
// make the right bar button a done button
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed)];
self.navigationItem.rightBarButtonItem = doneButton;
[doneButton release];
}
else {
// clear out our cancel button
self.navigationItem.leftBarButtonItem = nil;
// clear out the right bar button (done)
self.navigationItem.rightBarButtonItem = nil;
// make the right bar button an edit button
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editPressed)];
self.navigationItem.rightBarButtonItem = editButton;
[editButton release];
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
switch (textField.tag) {
case kOdometer:
[editModeDict setValue:textField.text forKey:@"Odometer"];
break;
case kQuantity:
[editModeDict setValue:textField.text forKey:@"Quantity"];
break;
case kPricePer:
[editModeDict setValue:textField.text forKey:@"PricePer"];
break;
case kPriceTotal:
[editModeDict setValue:textField.text forKey:@"PriceTotal"];
break;
case kStationName:
[editModeDict setValue:textField.text forKey:@"Name"];
break;
case kStationAddress:
[editModeDict setValue:textField.text forKey:@"Address"];
break;
case kStationCity:
[editModeDict setValue:textField.text forKey:@"City"];
break;
case kStationState:
[editModeDict setValue:textField.text forKey:@"State"];
break;
case kStationZip:
[editModeDict setValue:textField.text forKey:@"Zip"];
break;
case kNotes:
[editModeDict setValue:textField.text forKey:@"Notes"];
break;
default:
break;
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
sectionsArray = nil;
}
- (void)dealloc {
[sectionsArray release];
[editModeDict release];
[currentContext release];
[passedEntry release];
[super dealloc];
}
@end
Gdzie przydzielasz/edytujesz editModeDict? Czy na pewno wywoływana jest opcja [editModeDict setValue: forKey:]? Co wyjście z NSLog()? – Felix
Ha, opuścił tę część. editModeDict pobiera alokację i init w viewDidLoad. Jest to zdecydowanie poprawne. – Chuck
Wygląda na to, że działa, umieszczając \t [self.view.window endEditing: YES]; na początku mojej metody donePressed, która powoduje, że wszystkie edytowane, ale wciąż pierwsze pola tekstowe odpowiadające, przechodzą przez swoje metody edycji końca, co aktualizuje słownik. – Chuck