проблема протокола iphone - PullRequest
       21

проблема протокола iphone

1 голос
/ 11 апреля 2011

Я что-то здесь упускаю, где у меня есть класс EditableCell и протокол EditableCellDelegate, определенные для обработки ячейки таблицы для редактирования.(Оригинальный код взят из «iPhone для программистов» Пола Дейтеля).

Хотя я импортировал заголовок для EditableCell в мой файл ClientEditTVC.h, свойства и методы EditableCell не распознаются в ClientEditTVC.m,

Вот заранее написанный код для EditableCell.h и .m:

#import <UIKit/UIKit.h>

@protocol EditableCellDelegate; // declare EditableCellDelegate Protocol

@interface EditableCell : UITableViewCell <UITextFieldDelegate>
{
   id <EditableCellDelegate> delegate; // this class's delegate
   UITextField *textField; // text field the user edits
   UILabel *label; // label on the left side of the cell
} // end instance variables declaration

// declare textField as a property
@property (nonatomic, retain) UITextField *textField;

// declare label as a property
@property (readonly, retain) UILabel *label;

//declare delegate as a property
@property (nonatomic, assign) id <EditableCellDelegate> delegate;

- (void)setLabelText:(NSString *)text; // set the text of label
- (void)clearText; // clear all the text out of textField
@end // end interface EditableCell

@protocol EditableCellDelegate // protocol for the delegate

// called when the user begins editing a cell
- (void)editableCellDidBeginEditing:(EditableCell *)cell;

// called when the user stops editing a cell
- (void)editableCellDidEndEditing:(EditableCell *)cell;

// called when the user touches the Done button on the keyboard
- (void)editableCellDidEndOnExit:(EditableCell *)cell;
@end // end protocol EditableCellDelegate

И

#import "EditableCell.h"
@implementation EditableCell

@synthesize textField; // synthesize get and set methods for delegate
@synthesize label; // synthesize get and set methods for delegate
@synthesize delegate; // synthesize get and set methods for delegate

// initialize the cell
- (id)initWithStyle:(UITableViewCellStyle)style
    reuseIdentifier:(NSString *)reuseIdentifier
{
   // call the superclass
   if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
   {
      // create the label on the left side
      label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 0, 20)];

      // create the text field to the right of the label
      textField =
         [[UITextField alloc] initWithFrame:CGRectMake(0, 10, 0, 20)];

      [textField setDelegate:self]; // set the delegate to this object

      // call textFieldDidEndOnExit when the Done key is touched
      [textField addTarget:self action:@selector(textFieldDidEndOnExit)
          forControlEvents:UIControlEventEditingDidEndOnExit];
      [self.contentView addSubview:label]; // add label to the cell
      [self.contentView addSubview:textField]; // add textField to cell
   } // end if

   return self; // return this Editable cell
} // end method initWithFrame:reuseIdentifier:

// method is called when the user touches the Done button on the keyboard
- (void)textFieldDidEndOnExit
{
   [textField resignFirstResponder]; // make the keyboard go away
   [delegate editableCellDidEndOnExit:self]; // call the delegate method
} // end method textFieldDidEndOnExit

// set the text of the label
- (void)setLabelText:(NSString *)text
{
   label.text = text; // update the text

   // get the size of the passed text with the current font
   CGSize size = [text sizeWithFont:label.font];
   CGRect labelFrame = label.frame; // get the frame of the label
   labelFrame.size.width = size.width; // size the frame to fit the text
   label.frame = labelFrame; // update the label with the new frame

   CGRect textFieldFrame = textField.frame; // get the frame of textField

   // move textField to 30 pts to the right of label
   textFieldFrame.origin.x = size.width + 30;

   // set the width to fill the remainder of the screen
   textFieldFrame.size.width =
   self.frame.size.width - textFieldFrame.origin.x;
   textField.frame = textFieldFrame; // assign the new frame
} // end method setLabelText:

// clear the text in textField
- (void)clearText
{
   textField.text = @""; // update textField with an empty string
} // end method clearText

// delegate method of UITextField, called when a text field begins editing
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
   [delegate editableCellDidBeginEditing:self]; // inform the delegate
} // end method textFieldDidBeginEditing:

// delegate method of UITextField, called when a text field ends editing
- (void)textFieldDidEndEditing:(UITextField *)textField
{
   [delegate editableCellDidEndEditing:self]; // inform the delegate
} // end method textFieldDidEndEditing:

// free EditableCell's memory
- (void)dealloc
{
  [textField release]; // release the textField UITextField
  [label release]; // release the label UILabel
  [super dealloc]; // call the superclass's dealloc method
} // end method dealloc
@end // end EditableCell class definition

А вот соответствующий код из ClientEditTVC.h и.m

#import <UIKit/UIKit.h>
#import "EditableCell.h"


@interface ClientEditTVC : UITableViewController <UITableViewDataSource, EditableCellDelegate> {
    NSArray *fields;
    NSMutableDictionary *data;
    BOOL keyboardShown;
    EditableCell *currentCell;
}


@end

и

#import "ClientEditTVC.h"


@implementation ClientEditTVC

// stuff here

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[EditableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    // get the key for the given index path
    NSString *key =
    [fields objectAtIndex:indexPath.row + indexPath.section * 3];
    [cell setLabelText:key]; // update the cell text with the key

    // update the text in the text field with the value
    //cell.textField.text = [data valueForKey:key];


    return cell;
}

// more stuff here

@end

В строке [ячейка setLabelText: key]; появляется предупреждение о том, что UITableViewCell может не отвечать на setTableText.Но при трассировке через точки останова выполняется код setTextField в EditableCell.

Строка (закомментированная) для cell.textField.text выдает ошибку, свойство 'textField' не найдено вобъект типа 'UITableViewCell'

Очевидно, что компилятор не видит, что я подкласс UITableViewCell, и я не уверен, почему.Мне даже странно, что метод setLableText выполняется.Я вернулся к примеру кода, предоставленного Deitel, и эти проблемы не возникают.Я внимательно просмотрел свой код и не заметил существенной разницы.

Буду признателен за предложения о том, что я пропускаю.

Ответы [ 3 ]

2 голосов
/ 11 апреля 2011

Вы объявили cell как это:

UITableViewCell *cell;

Так что это не EditableCell. Если вы объявите это так:

EditableCell *cell;

это не даст вам предупреждения. Вероятно, он предупредит, что вы назначаете UITableViewCell на cell, но вы можете «исправить» это с помощью приведения, то есть

EditableCell *cell = (EditableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Кроме того, вам необходимо настроить тип возвращаемого значения функции. Это должно устранить все предупреждения компилятора.

1 голос
/ 11 апреля 2011

Переименовать cell как EditableCell * вместо UITableViewCell *, и это предупреждение должно исчезнуть.

0 голосов
/ 11 апреля 2011
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[EditableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

// Configure the cell...
// get the key for the given index path
    NSString *key = [fields objectAtIndex:indexPath.row + indexPath.section * 3];
    [cell setLabelText:key]; // update the cell text with the key

    if ([cell isKindOfClass:[EditableCell class]]) {
        EditableCell* editableCell = (EditableCell*)cell;
// update the text in the text field with the value
        editableCell.textField.text = [data valueForKey:key];
    }
    else {
        assert(0 && "is it alright that this instance is not an EditableCell?");
    }

    return cell;
}
...