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
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
Ha, để phần đó ra. editModeDict được cấp phát và init trong viewDidLoad. Nó chắc chắn là hợp lệ. – Chuck
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