I'm using storyboard for a tableview with custom cells. I created custom cells in storyboard without any additional classes for it. Everything works fine when I'm not using the UISearch bar, But when I want to create the custom cell for UISearchBarController tableview I don't know how can I do it.
Hers is my custom cell in storyboard,
with cellIdentifier = "SelectionCell"
and I'm not using any custom class.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SelectionCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = [nibs objectAtIndex:0];
}
the code crashes:
'Could not load NIB in bundle:'
I don't have a NIB file for my custom cell, and I don't have any custom UITableViewCell class to use alloc/init method like this:
cell = [[myCustomCellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
how can I create the cell?
searchResultsTableView
The table view in which the search results are displayed. (read-only)
#property(nonatomic, readonly) UITableView *searchResultsTableView
A search display controller manages the display of a search bar, along with a table view(your original tableview style) that displays search results.
It seems it can't be done without a custom cell class. Because we don’t have a storyboard prototype cell to manipulate graphically for the filtered table view, we have to programmatically create the cells. And for that we need a custom cell class and with initWithStyle: method in the .m file as follows.
So I created a class called SelectionCell subclass of UITableViewCell, and in IB assigned custom cell class to SelectionCell class and create IBOutlet for all UI controls in my custom cell into SelectionCell.h file
#interface SelectionCell : UITableViewCell{
}
#property (strong, nonatomic) IBOutlet UIImageView *contactPictureID;
#property (strong, nonatomic) IBOutlet UILabel *contactName;
#property (strong, nonatomic) IBOutlet UILabel *emailAddress;
#property (strong, nonatomic) IBOutlet UIImageView *selectedEmailState;
#end
in initWithStyle: method, I had to recreate all the UI controls programmatically and add them to the contentView as subviews:
// SelectionCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.selectionStyle = UITableViewCellSelectionStyleNone;
_contactPictureID = [[UIImageView alloc] initWithFrame:(CGRectMake(10, 14, 48, 48))];
_contactName = [[UILabel alloc] initWithFrame:(CGRectMake(66, 14, 201, 30))];
_contactName.font = [UIFont boldSystemFontOfSize:20];
_contactName.textAlignment = NSTextAlignmentLeft;
_emailAddress = [[UILabel alloc] initWithFrame:(CGRectMake(66, 41, 201, 21))];
_emailAddress.font = [UIFont systemFontOfSize:16];
_emailAddress.textAlignment = NSTextAlignmentLeft;
_selectedEmailState = [[UIImageView alloc] initWithFrame:(CGRectMake(275, 22, 32, 32))];
[self.contentView addSubview:_contactPictureID];
[self.contentView addSubview:_contactName];
[self.contentView addSubview:_emailAddress];
[self.contentView addSubview:_selectedEmailState];
}
return self;
}
Now I am able to instantiate my custom cell. In cellForRowAtIndexPath method
static NSString *CellIdentifier = #"SelectionCell";
SelectionCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SelectionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; }
And now everything is working as it should be.
Related
Previously when I create a UITableView using storyboard, I set the cell identifier in property inspector and paste it into method cellForRowAtIndexPath, then use method dequeueReusableCellWithIdentifier to create a new UITableViewCell. However, when I create a UITableView programmatically, I have nowhere to set up cell identifier. I mean, I can arbitrarily appoint an identifier without having to match that in the property inspector. Am I right? And how should I create a UITableViewCell under this situation?
You can create UITableview and UITableviewCell both programmatically as below.
Create Tableview Programmatically,
#interface ViewController () <UITableViewDataSource>{
//create tableview instance
UITableView *tableViewPro;
}
Alloc it in viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// init table view
tableViewPro = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
// must set delegate & dataSource, otherwise the the table will be empty and not responsive
tableViewPro.dataSource = self;
tableViewPro.backgroundColor = [UIColor cyanColor];
// add to canvas
[self.view addSubview:tableViewPro];
}
Assign number of rows and UITableview cell in Tableview datasource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Tableviewcell";
// Similar to UITableViewCell, but
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
//initialize uitableviewcell programmatically.
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
// Just want to test, so I hardcode the data
cell.descriptionLabel.text = [NSString stringWithFormat:#"Testing index %ld",(long)indexPath.row];
return cell;
}
Now, create your UITableviewCell programmatically. First Add New->file->Cocoa Touch class->Enter tableviewcellname with subclass-of UITableviewCell and UNCHECK the 'Also create XIB file', because cell will be created programmatically.
Two files will be created .h and .m of UITableviewCell, I've create UITableviewCell with TableViewCell name. below is the code to achieve it programmatically.
#interface TableViewCell : UITableViewCell
#property (nonatomic,retain) UILabel *descriptionLabel;
#end
Synthesize descriptionLabel in #implementation file of TableViewCell
#synthesize descriptionLabel = _descriptionLabel;
Below is the initialization function function of creating a UITableviewCell Programmatically. ADD THIS FUNCTION ON #implementation file of TableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
//it will create UITableiviewCell programmatically and assign that instance on self.
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// configure control(s)
self.descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 10, 300, 30)];
self.descriptionLabel.textColor = [UIColor blackColor];
self.descriptionLabel.font = [UIFont fontWithName:#"Arial" size:12.0f];
[self addSubview:self.descriptionLabel];
}
return self;
}
Below is the resulted output.
I created a custom table cell that expands. When it expands, it shows a UILabel along with two UIButtons. The UILabel should show data from the backend. I created the customLabel in the CustomCell interface file. Then I imported the CustomCell class into my InboxTableViewController, and implemented the custom cell. The label only appears when the cell is tapped, and expands. How would I go about changing the UILabel, because cell.customLabel.text, would not work here, since it is not a property of the cell. Here is the associated code:
CustomCell.h
#interface CustomCell : UITableViewCell
{
UIImage *userImage;
UILabel *userName;
//below widgets will display when user tapped
#public
UIButton *leftButton, *rightButton;
UILabel *customLabel;
BOOL userTapped;
}
#property (weak, nonatomic) IBOutlet UILabel *userName;
#property (weak, nonatomic) IBOutlet UIImageView *userImage;
- (void) setData:(NSDictionary*) d;
#end
and here is the inboxviewcontroller.m where i try to implement the customcell along with the customLabel.
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// PFObject *message = [self.messages objectAtIndex:indexPath.row];
PFObject *message = [self.messages objectAtIndex:indexPath.row];
cell.userName.text = [message objectForKey:#"from"];
//cell.userImage.image = [message objectForKey:#"image1"];
cell.customLabel.text = [message objectForKey:#"message"];
return cell;}
This will not work as you are creating instance of CustomCell directly instead you have to load CustomCell view from nib so it will create instance of customLabel and using this you can set text, use below code
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"CustomCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
}
For custom UITableViewCell's you should take a look at this tutorial . It will give you the idea.
I have a tableview with custom cells inside a view controller. My tableview works properly. What I am trying to do is develop the image below programmatically. Where "label" is the text that is custom and changes depending on some input. How can I include these 2 labels (in cellForRowAtIndexPath:) and determine their position in the cell.
Image contains 2 different table cells.
I am aware how to do it through storyboard, but I need to do it programmatically cause I am using dynamic cells in xCode 4.5.
The image refers to the index cells 1 and 2. I have only managed to include one text label per cell till now.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
switch ([indexPath row])
{
case 0:
{
// image cell - image resize and centred
UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(30,2, 180, 180)];
imv.image=[UIImage imageNamed:#"test1.jpg"];
imv.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
[cell.contentView addSubview:imv];
imv.center = CGPointMake(cell.contentView.bounds.size.width/2,cell.contentView.bounds.size.height/2);
cell.accessoryType = UITableViewCellAccessoryNone;
break;
}
case 1:
{
cell.textLabel.text = #"Name";
break;
}
case 2:
{
cell.textLabel.text = #"Manufacturer";
break;
}
case 3:
{
cell.textLabel.text = #"Overall Score";
break;
}
case 4:
{
cell.textLabel.text = #"Description";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
break;
}
case 5:
{
cell.textLabel.text = #"Videos";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
break;
}
}
return cell;
}
Thank you in advance
Check the default UITableViewCell styles first: UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle.
If you can use them, you don't need to subclass UITableViewCell. Otherwise you're going to have to do just that and put 3 properties down: a UIView and 2 UILabel's. The reason is if you don't use default cell styles, you cannot move or add cell elements.
Your UITableViewCell subclass should have the following code:
#interface UITableViewCellSubClass : UITableViewCell
#property (nonatomic, strong) UIView *view;
#property (nonatomic, strong) UILabel *label1;
#property (nonatomic, strong) UILabel *label2;
#end
#implementation UITableViewCellSubClass
#synthesize view;
#synthesize label1;
#synthesize label2;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
view = [[UIView alloc] initWithFrame:self.frame];
[self addSubview:view];
// initiate label1 with position (10,10,150,20)
label1 = [[UILabel alloc] initWithFrame:CGRectMake(10,10,150,20)];
// initiate label2 with position (170,10,150,20)
label2 = [[UILabel alloc] initWithFrame:CGRectMake(170,10,150,20)];
[view addSubview:label1];
[view addSubview:label2];
}
return self;
}
#end
Then you can return that in your cellForRowAtIndex: method and basically:
UITableViewCellSubclass *cell = [[UITableViewCellSubclass alloc] initWithStyle:UITableViewCellDefault reuseIdentifier:#"cell"];
[cell.label1 setText:#"text"];
[cell.label2 setText:#"more text"];
Hope this helps and don't forget to #import "UITableViewCellSubClass.h"
I have created a subclass of UITableViewCell and I called it DCCustomCell. This is the DCCustomCell.h file.
#import <UIKit/UIKit.h>
#interface DCCustomCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UILabel *title;
#property (weak, nonatomic) IBOutlet UILabel *date;
#property (weak, nonatomic) IBOutlet UILabel *price;
#end
All the proprieties are correcty connected with elements in my iPhone.storyboard file.
I also selected the tableViewCell in iPhone.storyboard and i setted my cell's identifier to "CustomCell" and the class to DCCustomCell.
This is the UITableViewController's viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[DCCustomCell class] forCellReuseIdentifier:#"CustomCell"];
// Do any additional setup after loading the view, typically from a nib.
}
and this is the tableView:cellForRowAtIndexPath: method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"CustomCell";
DCCustomCell *cell = (DCCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
NSLog(#"%#" ,cell);
cell.imageView.image = [UIImage imageNamed:#"info_button.png"];
cell.title.text = #"Hello!";
cell.date.text = #"21/12/2013";
cell.price.text = #"€15.00";
return cell;
}
The problem is that the imageView is correctly setted, but all the labels are blank. If I change the imageView property name to, for example, eventImageView, the image will not be setted.
This is the result:
I can't figure out how I can solve this problem.
EDIT: if I remove
[self.tableView registerClass:[DCCustomCell class] forCellReuseIdentifier:#"CustomCell"];
from viewDidLoad all seems to work. why?
As you noticed it works when you remove
[self.tableView registerClass:[DCCustomCell class] forCellReuseIdentifier:#"CustomCell"];
You only have to do this if you use dequeueReusableCellWithIdentifier:indexPath: AND have not already set the custom class in the identity inspector for that cell. If you use registerClass: forCellReuseIdentifier the cell will be initialized with initWithStyle:reuseIdentifier: instead of initWithCoder: thus screwing up your connections you made in the storyboard.
Have you bind the Controls to IBOutlet ?
You can try setting DCCustomCell to UITableviewCell's class directly in Storyboard.
And than you need to set outlets with controls in cell
Try:
if (cell == null) {
//create and initialize cell
}
after
DCCustomCell *cell = (DCCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
You first check your outlets properly that all the labels are connected & write this also :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"CustomCell";
DCCustomCell *cell = (DCCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DCCustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSLog(#"%#" ,cell);
cell.imageView.image = [UIImage imageNamed:#"info_button.png"];
cell.title.text = #"Hello!";
cell.date.text = #"21/12/2013";
cell.price.text = #"€15.00";
return cell;
}
Hi I have an requirement to customize UITableViewCell. Hence I have created a custom class and necessary UI (xib) to support it. For the XIB I have chosen the class as the derived class that I have created. My Problem is when after linking the display labels to the properties and me setting the values at runtime does not display the text desired. Its left as blank. Below is the code snippet.
#interface CustomCell : UITableViewCell
{
IBOutlet UILabel *titleRow;
}
#property (nonatomic, strong) UILabel *titleRow;
#property (nonatomic, strong) UILabel *subTitleRow;
#property (nonatomic, strong) UILabel *otherTextRow;
#end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MedVaultCell";
CustomCell *cell = nil;
cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (nil == cell){
//Load custom cell from NIB file
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellHistoryCell" owner:self options:NULL];
cell = [nib objectAtIndex:0];
//cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
// get the object
Weight *currentCellWeight = [_weights objectAtIndex:indexPath.row];
// Configure the cell...
UILabel *titleLable = [[UILabel alloc]init];
titleLable.text = currentCellWeight.customDispText;
[cell setTitleRow:titleLable];
cell.titleRow.text = currentCellWeight.display;
cell.titleRow.textColor = [UIColor redColor];
//cell.textLabel.text = [[_weights objectAtIndex:indexPath.row] customDispText];
//cell.textLabel.textColor = [UIColor whiteColor];
return cell;
}
First, I hope your cellForRowAtIndexPath is in your UITableView delegate, not in your custom cell class.
Secondly, here is the problem:
// Configure the cell...
UILabel *titleLable = [[UILabel alloc]init];
titleLable.text = currentCellWeight.customDispText;
[cell setTitleRow:titleLable];
In this code you are creating a new label and overriding your IBOutlet label with the new label. Then you are not displaying the new label. Instead, change the code to this:
// Configure the cell...
cell.titleRow.text = currentCellWeight.customDispText;
However, you then reset the titleRow.text right after it to currentCellWeight.display.
So you need to pick which one of those you want to be the text and set the text to that. You do not need to create a new label (UILabel *titleLable = [[UILabel alloc] init];) because you have already created the label in IB.