2010-12-31 11 views
5

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 
+0

Gdzie przydzielasz/edytujesz editModeDict? Czy na pewno wywoływana jest opcja [editModeDict setValue: forKey:]? Co wyjście z NSLog()? – Felix

+0

Ha, opuścił tę część. editModeDict pobiera alokację i init w viewDidLoad. Jest to zdecydowanie poprawne. – Chuck

+0

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

Odpowiedz

0

Spróbuj tego:

utworzyć metodę

-(NSString *)getInEditTextFieldValue 
    { 
     if([myTextField isFirstResponder]) 
    { 
      // get the text of myTextField and set it to text. 
      return myTextField.text; 
    } 
    else 
    { 
      return nil; 
    } 
    } 

iw swoim donePressed:

-(void)donePressed 
    { 
     NSString* myText = [self getInEditTextFieldValue]; 

     if(myText != nil) 
     { 
       // add myText to your dictionary 
     } 

     // save logic goes here... 

     // reload data for table view... 
    } 

nie jestem z moim mac, tak teraz nie mogę spróbować kod , ale logika wyzywająco działała dla mnie. Twoje metody UITextFieldDelegate powinny pobierać wartości wszystkich pól tekstowych oprócz tego, który jest pierwszym respondentem. To, co musisz zrobić, to trochę więcej pracy, aby sprawdzić i uzyskać wartość.

Mam nadzieję, że to może ci pomóc.

0

Najpierw należy odwołać się do pola tekstowego odpowiednio w UITableCell. Następnie po kliknięciu przycisku done button można również uzyskać obiekt komórki. Na podstawie contentView obiektu typu (w przypadku typu UITextField) można uzyskać & można uzyskać z niego tekst. W ten sposób możesz zaktualizować bazę danych dla wszystkich pól.

0

Twój doneButton() zostanie wywołany przed textFieldShouldEndEditing.Spróbuj zmienić osobę odpowiadającą, a zobaczysz, że jedna aktywna w czasie kliknięcia doneButton nie zapisze danych.

Powiązane problemy