2010-12-31 14 views
5

Şimdi bir ya da iki gün boyunca kafamı becermeye başladım ve istediğim gibi çalışamıyorum. Adres defterinin iletişim düzenleme sayfasını taklit etmeye çalışıyorum (daha önce sorulduğunu biliyorum).düzenlenebilir UITableView, bir hücreye UITextView, bittiğinde veri depolama

Özel bir UITableViewCell, ayrıntı metni etiketiyle aynı yerde bulunan bir UITextField içerir ve düzenleme düğmesine basıldığında, doğru öğeleri göstermek için gizlenir ve görünürler.

UITextFieldDelegate, metin alanlarına yazılan bilgileri bir sözlükte saklamak için kullanıyorum, böylece kullanıcı "bitti" yi tıklattığında bunları görüntü dizisine ve temel veri modeline kaydedebiliyorum.

Şimdi sorun: Bir alana metin girilirse, başka bir alan/hücre seçilmez ve yapılmaz, değiştirilen bilgi dikkate alınmaz, hiçbir zaman sözlükte depolanmaz.

Benim kodum şu anda, yalnızca sözlüğün içeriği doğru olduğunda yalnızca sözlüğün içeriğini NSLog'a basıyor; çünkü, sözlüğün durumu doğru olana kadar hücreyi güncellemeye başladım.

Her şeyin iş akışını izlemeye çalışmak için koşturulduğunda, günlük baskıları ile tüm UITextFieldDelegate yöntemlerini listeledim, ancak bu özel sorun hakkında kafamı sarmamda bana yardımcı olmadı. İşte

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

DüzenleModeDict'ı nereye ayırıyorsunuz? [EditModeDict setValue: forKey:] çağrıldığından emin misiniz? NSLog() çıktısı nedir? – Felix

+0

Ha, bu bölümü bıraktı. editModeDict, viewDidLoad öğesinde atama ve init alır. Kesinlikle geçerli. – Chuck

+0

Görünüşe göre \t [self.view.window endEditing: YES]; Düzenlenmiş, ancak yine de ilk yanıtlayıcı metin alanlarının tümünü yapan, sözlükte güncellenen son düzenleme yöntemlerini kullanan donePressed yöntemimin başında. – Chuck

cevap

0

bu deneyin:

bir yöntemini

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

oluşturmak ve donePressed içinde:

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

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

     // save logic goes here... 

     // reload data for table view... 
    } 

ben artık mac birlikte değilim o yüzden kod deneyemiyoruz Ama mantık meydan okurcasına benim için çalıştı. UITextFieldDelegate yöntemleriniz, ilk yanıtlayanın dışında sahip olduğunuz tüm metin alanlarının değerlerini almalıdır. Yapman gereken, değeri kontrol etmek ve almak için biraz daha fazla çalışmak.

Bu yardımcı olabilir umarım.

0

Metin alanınıza ilk olarak UITableCell numaralı telefondan başvurmanız gerekir. Daha sonra bitmiş düğme düğmesine tıkladığınızda hücre nesnesini de alabilirsiniz. Yazım nesnesinin contentView (UITextField tipinde) temel alınarak & elde edilebilir. Bu şekilde veritabanınızı tüm alanlar için güncelleyebilirsiniz.

0

doneButton() işleminiz textFieldShouldEndEditing öğesinden önce çağrılır.Yanıtlayıcıyı değiştirmeye çalışın ve doneButton tıklamasının etkin olduğu zamanın verilerini kaydetmeyeceğini göreceksiniz.