редактируемый UITableView, UITextField в ячейке, сохранение данных, когда готово нажата - PullRequest
5 голосов
/ 31 декабря 2010

Я бьюсь головой об этом уже день или два, и не могу заставить его работать так, как я хочу.Я пытаюсь имитировать страницу редактирования контактов в адресной книге (я знаю, что ее уже спрашивали).

У меня есть пользовательский UITableViewCell, который включает в себя UITextField, который находится в том же месте, что и метка подробного текста, ипри нажатии кнопки редактирования они прячутся и отображают правильные элементы.

Я использую UITextFieldDelegate для хранения информации, набранной в текстовых полях, в словарь, чтобы сохранить их в массиве представления имоя основная модель данных, когда пользователь нажимает «готово».

Теперь проблема: если текст введен в поле, никакое другое поле / ячейка не выбрано и нажата кнопка «Готово», измененная информация игнорируется,никогда не сохраняется в словаре.

Мой код прямо сейчас печатает содержимое словаря в NSLog только когда нажата кнопка «Готово», потому что я не вижу смысла обновлять ячейку до тех пор, пока сначала не будет исправлено состояние словаря..

Я перечислил все методы UITextFieldDelegate с распечатками журнала, когда каждая вещь запускается, чтобы попытатьсяВот как это происходит, но это не помогло мне обойти эту конкретную проблему.

Вот код:

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

Ответы [ 3 ]

0 голосов
/ 21 сентября 2012

Сначала вам нужно правильно сослаться на текстовое поле в UITableCell.Затем по нажатию кнопки «Готово» вы также можете получить объект ячейки.На основе contentView вашего типа объекта (в вашем случае типа UITextField) можно получить, и вы можете получить текст из него.Таким образом, вы можете обновить свою базу данных для всех полей.

0 голосов
/ 17 января 2013

Ваш doneButton () вызывается перед textFieldShouldEndEditing. Попробуйте изменить респондента, и вы увидите, что один из активных во время нажатия кнопки DoneButton не сохранит свои данные.

0 голосов
/ 20 июля 2012

Попробуйте это:

создайте метод

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

и в вашем donePressed:

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

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

        // save logic goes here...

        // reload data for table view...
  }

Я сейчас не со своим Mac, поэтому я не могу попробоватькод, но логика у меня демонстративно сработала.Ваши методы UITextFieldDelegate должны получить значения всех текстовых полей, которые у вас есть, кроме того, которое является первым респондентом.Вам нужно еще немного поработать, чтобы проверить и получить значение.

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...