Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a custom UITableViewCell class created in IB to load into a UITableView?

I am new to this so please bear with me:

I have a .xib in IB containing a UIScrollView that has a UITableView embedded in it. I would like to load custom UITableViewCells into the UITableView. I have four/five custom cells created in IB but cannot get the first to load correctly.

Here are relevant screenshots from IB:

.xibcustom cell "itemCell"

I have set the class for the custom UITableViewCell created in IB to the UITableView class I created called "itemCell". Additionally, I have connected the three text fields outlets and delegates to "itemCell".

Here is itemCell.h:

#import <UIKit/UIKit.h>

@interface itemCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UITextField *quantityTextField;
@property (weak, nonatomic) IBOutlet UITextField *itemTextField;
@property (weak, nonatomic) IBOutlet UITextField *priceTextField;

@end

Here is itemCell.m:

#import "itemCell.h"

@implementation itemCell
@synthesize quantityTextField,itemTextField,priceTextField;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code

    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

In filecontroller.m, which is the rootcontroller .xib's implementation file I create a new cell based on the user pressing a button (add it to an array) and then reload the tableview. I am getting no errors but I am getting a normal cell loaded in rather than what I have created in IB. Here is rootcontroller.m. Any help is appreciated.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    scrollView =(UIScrollView *)self.view;
    items = [[NSMutableArray alloc] init];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [items count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        return [items objectAtIndex:[indexPath row]];
}

- (UITableViewCell *)initiateNewCell{
    itemCell *cell = [[itemCell alloc] init];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    return cell;
}

- (IBAction)addItem:(id)sender {
    //creates the new cell to be added
    [items addObject:[self initiateNewCell]];
    [self.tableView reloadData];
like image 988
IkegawaTaro Avatar asked Dec 29 '12 23:12

IkegawaTaro


3 Answers

As of iOS 5 you can now load a UITableViewCell from a nib for cell reuse with the following function.

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

  1. First make sure you create an IB file that contains only the UITableViewCell
  2. Under Identify inspector: Set the class of the UITableViewCell to "itemCell" enter image description here
  3. Under attributes inspector: Set the identifier of the UITableViewCell to "itemCellIdentifier" enter image description here
  4. In viewDidLoad: place the following code, and replace itemCellNibName with the name of the nib that contains the UITableViewCell.

    NSString *myIdentifier = @"itemCellIdentifier";
    [self.tableView registerNib:[UINib nibWithNibName:@"itemCellNibName" bundle:nil] forCellReuseIdentifier:myIdentifier];
    
  5. In cellForRowAtIndexPath: place the following code, you can now access your IBOutlet properties you set on the itemCell, and connected in the nib.

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
         static NSString *myIdentifier = @"itemCellIdentifier";
    
         itemCell *cell = (itemCell *)[tableView dequeueReusableCellWithIdentifier:myIdentifier];
         cell.textLabel.text = [NSString stringWithFormat:@"Test Row:%i!",indexPath.row];
         return cell;
    }
    

Also: You do not want to include the UITableView inside a UIScrollView, a UIScrollView is already built into the UITableView, which allows for proper cell queing.

Also: I suggest you just get the bare bones of this going first, before you start pulling data from an array.

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
         return 10;
    }

Also: As someone else had mentioned, the array contains the data that will populate the UITableViewCells, not the actual cells themselves.

like image 197
Josh Bernfeld Avatar answered Nov 09 '22 18:11

Josh Bernfeld


In your

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

    //This identifier string needs to be set in cell of the TableViewController in the storyboard
    static NSString *CellIdentifier = @"Cell";

    // Resuse the cell
    SomeCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // If there are no cell to be reused we create a new one
    if(cell == nil) {
        cell = [SomeCustomCell new];
    }

    // Configure the cell...
    NSString *someString = [yourArrayWithStringsOrWhatEver objectAtIndex:indexPath.row];

    // Setting the some property of your custom cell
   [cell.yourSpecificCellProperty someString];

   [cell.yourOtherSpecificCellProperty setText:@"What Ever your want!"];
}

Your cell's properties could be whatever your have connected to your custom cell in interface builder.

Hope it helps!

like image 44
Groot Avatar answered Nov 09 '22 16:11

Groot


Well there are a few things that aren't right:

  • The class name begins with upper case letter itemCell -> ItemCell
  • You should reuse the cell. The way you want to do this, you will create a separate cell for each index path.
  • the items array should only contain the data source of your table, not your cells
  • instead of calling reload data, you can add just one row to the table, and it can be animated too

Try something like:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    scrollView =(UIScrollView *)self.view;
    items = [[NSMutableArray alloc] init];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [items count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[NSBundle mainBundle] loadNibNamed:@"itemCell" owner:self options:nil].lastObject;
        cell.reuseIdentifier = CellIdentifier;
    }

    // Do any additional setup to the cell

    return cell;
}

- (IBAction)addItem:(id)sender {
    [items addObject:[NSNumber numberWithInt:items.count]]; // Here comes the data source
    [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:items.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
}

PS: I wrote it without an IDE so there might be some errors

like image 29
Levi Avatar answered Nov 09 '22 18:11

Levi