Domanda

I have a custom static UITableViewCell that I want to look exactly the same as a right detail cell (UILabel on the left, UILabel on the right), except I want the right UILabel to be an editable UITextField. Since I want to use this cell in multiple view controllers in my storyboard, I decided the best option would be to create a MyEditableTableViewCell.xib file, along with corresponding *.h,m files. I have two public properties in MyEditableTableViewCell.h:

@property (weak, nonatomic) IBOutlet UILabel *textLabel;
@property (weak, nonatomic) IBOutlet UITextField *detailTextField;

These IBOutlets are connected to the UILabel and UITextField in the .xib file. In my storyboard, where I have a custom UITableViewController subclass, I change the class of the necessary UITableViewCell to MyEditableTableViewCell. I have a property in my view controller that is:

@property (weak, nonatomic) IBOutlet MyEditableTableViewCell *myCell;

However, when I run the app, the cell appears as simply a blank cell. Running some checks on it, I see that [myCell isKindOfClass:[MyEditableTableViewCell class]] returns true. However, the UITextField never seems to get instantiated. When I try to alter myCell.detailTextField.text, nothing happens, and myCell.detailTextField appears to be nil.

Any help would be appreciated!

È stato utile?

Soluzione

How are you creating instances of MyEditableTableViewCell? My guess is you're doing [[MyEditableTableViewCell alloc] init] instead of loading them from the nib.

You don't need that property in your view controller. You need to register your cell nib with the table view using -[UITableView registerNib:forCellReuseIdentifier:]. Do that in your viewDidLoad. Then, when you send dequeueReusableCellWithIdentifier: to the table view, it will instantiate the nib, creating a MyEditableTableViewCell, and return it to you.

UPDATE

If you're laying out static cells in a storyboard, using a xib to lay out a cell is somewhat difficult. The simplest thing to do is simply lay out the cell's subviews in the storyboard. You can copy and paste the subviews to each cell if you have a few of the same type.

If you really want to use a xib, the easiest way is to structure your cell's view hierarchy like this:

MyEditableTableViewCell (in storyboard)
|
+- cell's content view (created automatically by UIKit)
   |
   +- UIView (top-level view of the xib)
      |
      +- UILabel (textLabel)
      |
      +- UITextField (detailTextField)

So you set the cell class in the storyboard to MyEditableTableViewCell. Then you create your xib. You set your xib File's Owner class to MyEditableTableViewCell. The xib does not contain a MyEditableTableViewCell. The top-level view of the xib is just a plain UIView, containing the subviews (the label and the text field).

In -[MyEditableTableViewCell initWithCoder:], after doing self = [super initWithCoder:aDecoder], instantiate the xib, passing self (the cell) as the xib file's owner. The cell can have outlets connected to the label and the text field in the xib.

After instantiating the xib, add the top-level view from the xib as a subview of self.contentView. If you're using auto layout, create constraints betwixt the top-level view and the content view. Otherwise, set the top-level view's frame to the content view's bounds and set the autoresizing mask to UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight.

Altri suggerimenti

Although a static table view will not fetch your cell from the nib, it will still call cellForRowAtIndexPath. There you can dequeue and return your fully unarchived custom cell. Properties on the custom cell that were set in IB, can be fetched by calling super on cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // get an empty cell with properties retained from IB
    UITableViewCell *sup = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    if ([sup isKindOfClass:[MyCustomCell class]]) {
          // fetch a fully unarchived cell
          MyCustomCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"foo" forIndexPath:indexPath];

          // copy properties over...
          [cell copyPropertiesFromCell:(MyCustomCell *)sup];

          return cell;
    }
    return sup;
}

Depending on the situation, this might actually be easier than to mess with IB objects.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top