2010-12-31 31 views
5

Tôi đã đập đầu của tôi về điều này trong một hoặc hai ngày và không thể làm cho nó hoạt động theo cách tôi muốn. Tôi đang cố gắng bắt chước trang chỉnh sửa liên hệ của sổ địa chỉ (tôi biết nó đã được hỏi trước đó).UITableView có thể chỉnh sửa, UITextField trong một ô, lưu trữ dữ liệu khi thực hiện được nhấn

Tôi có UITableViewCell tùy chỉnh bao gồm UITextField, nằm ở cùng vị trí với nhãn văn bản chi tiết và khi nhấn nút chỉnh sửa, chúng ẩn và hiện ra các mục chính xác.

Tôi đang sử dụng UITextFieldDelegate để lưu thông tin được nhập vào trường văn bản vào từ điển để tôi có thể lưu chúng vào mảng chế độ xem và mô hình dữ liệu cốt lõi của mình khi người dùng nhấp "xong".

Bây giờ vấn đề: Nếu văn bản được nhập vào một trường, không có trường/ô khác được chọn và thực hiện xong, thông tin đã thay đổi bị bỏ qua, nó sẽ không bao giờ được lưu trữ trong từ điển.

Mã của tôi ngay bây giờ chỉ in nội dung từ điển sang NSLog khi xong, vì tôi không thấy điểm cập nhật ô cho đến khi trạng thái của từ điển chính xác trước.

Tôi liệt kê ra tất cả các phương thức UITextFieldDelegate với các bản ghi nhật ký khi mỗi thứ được chạy để cố gắng theo dõi mọi thứ đang chảy như thế nào, nhưng nó không giúp tôi quấn quanh vấn đề cụ thể này.

Dưới đây là các mã:

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

Bạn phân bổ/init editModeDict ở đâu? Bạn có chắc chắn rằng [editModeDict setValue: forKey:] đang được gọi? Whats đầu ra của NSLog()? – Felix

+0

Ha, để phần đó ra. editModeDict được cấp phát và init trong viewDidLoad. Nó chắc chắn là hợp lệ. – Chuck

+0

Có vẻ như tôi đã làm việc đó bằng cách đặt \t [self.view.window endEditing: YES]; ở đầu phương thức donePressed của tôi, làm cho tất cả các trường văn bản trả lời tự động nhưng vẫn được trả lời đầu tiên đi qua các phương thức chỉnh sửa cuối của chúng, cập nhật từ điển. – Chuck

Trả lời

0

Hãy thử điều này:

tạo ra một phương pháp

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

và trong donePressed của bạn:

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

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

     // save logic goes here... 

     // reload data for table view... 
    } 

Tôi không có mac của tôi bây giờ vì vậy tôi không thể thử mã , nhưng logic thách thức làm việc cho tôi. Các phương thức UITextFieldDelegate của bạn sẽ nhận các giá trị của tất cả các trường văn bản mà bạn có, ngoại trừ một trong những phương thức trả lời đầu tiên. Những gì bạn phải làm là một ít công việc hơn để kiểm tra và nhận được giá trị.

Hy vọng điều này có thể giúp bạn.

0

Trước tiên, bạn cần tham chiếu trường văn bản của mình theo cách UITableCell. Sau đó, nhấp vào phương thức nút xong, bạn cũng có thể lấy đối tượng ô. Dựa trên contentView đối tượng loại của bạn (trong trường hợp của bạn là loại UITextField) có thể được lấy & bạn có thể lấy văn bản từ nó. Bằng cách đó bạn có thể cập nhật cơ sở dữ liệu của mình cho tất cả các trường.

0

Your doneButton() được gọi trước khi textFieldShouldEndEditing.Cố gắng thay đổi trả lời và bạn sẽ thấy rằng một trong những hoạt động trong thời gian doneButton nhấp chuột sẽ không lưu dữ liệu của nó.

Các vấn đề liên quan