I have a UITableView with CustomCell. The custom cells contain a UILabel and a UIImageView.
I saw online that it is possible to get the text from a normal UITableView cell and store it in a string when the user presses the cell.
But how can you do this when you are using a custom cell? Becuase the name of my UILabel is "type_label" and it has been defined in the header file of my CustomCell XIB.
So in Xcode I can't use:
cell.type_label.text"
In the following function:
-(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Thanks, Dan.
In the tableViewDidSelectRow all you need to do is:
UITableViewCellCustomClass *customCell = (UITableViewVellCustomClass*)[tableView cellForRowAtIndexPath:indexPath];
NSString *labelText = [[customCell type_label] text];
That should get you want you need.
Try below code - You have create type_label label's IBOutlet in CCustomCellClass
(file-->new-->subclass--> UITableViewCell-->name it like CustomCellClass)
Then implement below code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Cell";
static BOOL nibsRegistered = NO;
if (!nibsRegistered) {
UINib *nib = [UINib nibWithNibName:#"CustomCellClass" bundle:nil];
[tableView registerNib:nib forCellReuseIdentifier:cellIdentifier];
}
CustomCellClass *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CustomCellClass alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.type_label.text = #"Rocky"; // setting custom cell label
return cell;
}
Related
My table simply has row with a UIImageView. When I assign the image directly like the below mentioned way
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = #"cellidentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
// Configure the cell...
cell.imageView.image = [self.backgroundImages objectAtIndex:indexPath.row];
return cell;
}
It returns error:
unable to dequeue a cell with identifier cellidentifier - must
register a nib or a class for the identifier or connect a prototype
cell in a storyboard'.
So I wonder is there a way to ignore to register a nib or a class for UITableViewCell in order to shorten the code in this case?
If you are using custom class for your cell then you should register the class (in viewDidLoad),use registerNib:forCellWithReuseIdentifier: if the cell is made in a xib file.
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
else write cellForRowAtIndexPath tableView delegate as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//Configure cell
return cell;
}
You just need to add one line in your viewDidLoad to resolve the error
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cellidentifier"];
}
Put your cell identifier in storyboard as below screenshot.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Songcell"; // copy this identifier and paste it into your storyboard tableviewcell indetifier
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UIImageView *IMAGEVIEWNAME = (UIImageView*)[cell viewWithTag:YOUR_TAG]; // give tag to your imageview from storyboard and access it here
IMAGEVIEWNAME.image = [UIImage imageNamed:#"YOURIMAGENAME"];
return cell;
}
Give same name in your storyboard tableviewcell identifier
cellidentifier with this name . i just give my cell identifier songcell.
I have XIB that contain UITableView and in same XIB i created UITableViewCell, I did not set any class to cell, I just set identifier to the cell.
Now I want to load that cell to tableview delegate methd cellForRowAtIndexPath
i did is :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
return cell;
}
but it create new cell that doesn't include xib that i created.
So how do i get that cell from same xib that table view has ?
If you are creating a custom cell, then it will be better if you create custom classes of UITableViewCell type and then instantiate your UITableViewCell class in method.If you dont want to create custom class then below is the code that can help you:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"SimpleTableItem";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil)
{
cell = (UITableViewCell *)[[[NSBundle mainBundle] loadNibNamed:#"TMPartnerLoyalty" owner:self options:nil] objectAtIndex:0];
}
return cell;
}
Here, TMPartnerLoyalty is name of the xib.
please write this code in viewdidload , i hope it will work for you.
NSString *nibName = #"give your xib name here that contain Tablecell";
NSString *simpleTableIdentifier = #"SimpleTableItem";
UINib *customCellNib = [UINib nibWithNibName:nibName bundle:nil];
[tableView registerNib:customCellNib forCellReuseIdentifier:simpleTableIdentifier];
If you use prototype cell,Identifier name must same as dequeueReusableCellWithIdentifier name
NOTE:If you use prototype cell, you don't need to register the cell.Because Prototype cell is not a CustomCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell =[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"";
return cell;
}
If you use UITableViewcell(Custom cell),follow the below steps
1.in viewDidLoad you must register the UITableViewCell or Custom Cell
UINib *cellNib = [UINib nibWithNibName:#"YourUITableViewCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"cell"];
2.OR in cellForRowAtIndexPath you can write the code below like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customTableIdentifier=#"cell";
YourUITableViewCell *cell=(YourUITableViewCell*)[tableView dequeueReusableCellWithIdentifier:customTableIdentifier];
if (cell==nil)
{
NSArray *nibs=[[NSBundle mainBundle]loadNibNamed:#"YourUITableViewCell" owner:self options:nil];
cell=[nibs objectAtIndex:0];
}
cell.yourTableViewCellLabel.text = #"";
cell.yourTableViewCellTextField.text = #"";
cell.yourTableViewCellButton.text = #"";
return cell;
}
Trying to set and access nib tableview cell. Basically the same as creating uitableview with a prototype tableviewcell and setting its identifier and accessing it through
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Fill table in with data
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
Question is how would you do this as a nib. As nib IB doesn't have prototype option?
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
MPMediaItem *song = [self.songsList objectAtIndex:indexPath.row];
NSString *songTitle = [song valueForProperty: MPMediaItemPropertyTitle];
NSString *durationLabel = [song valueForProperty: MPMediaItemPropertyGenre];
cell.textLabel.text = songTitle;
cell.detailTextLabel.text = durationLabel;
return cell;
}
-(void)viewDidLoad {
[self.tableView registerNib:[UINib nibWithNibName:#"MusicViewController" bundle:nil] forCellReuseIdentifier:#"Cell"];
}
Create a custom tableviewCell with the nib file.After creation you have three files YourCustomCell.h YourCustomCell.m and YourCustomCell.xib
Add the IBOutlet in YourCustomCell.h and connect them in YourCustomCell.xib with respective labels.
Now in cellForRowAtIndexPath: add the following:
YourCustomCell *yourCustomCell = [self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
yourCustomCell.labelInCustomCell.textLabel.text = songTitle;
yourCustomCell.detailsLabelInCustomCell.textLabel.text = durationLabel;
return yourCustomCell;
Hope this help you.
You make your cell in the xib file and then in code (probably in viewDidLoad) register the nib with registerNib:forCellReuseIdentifier:. In cellForRowAtIndexPath, you just dequeue a cell with the same identifier that you passed to the register method. No need to put in the if (cell == nil) clause, because it will never be nil.
i was following this torturial:
http://www.raywenderlich.com/32283/core-graphics-tutorial-lines-rectangles-and-gradients
It covers customization of dynamic table cells, i need to do it with static table cells.
I have given every cell the identifier "Cell", as he does in the tutorial, i then subclassed the table view controller and implemented this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// START NEW
if (![cell.backgroundView isKindOfClass:[CostumCellBackground class]]) {
cell.backgroundView = [[CostumCellBackground alloc] init];
}
if (![cell.selectedBackgroundView isKindOfClass:[CostumCellBackground class]]) {
cell.selectedBackgroundView = [[CostumCellBackground alloc] init];
}
// END NEW
cell.textLabel.backgroundColor = [UIColor clearColor]; // NEW
return cell;
}
CostumCellBackground draws the rect.
I am getting the error "UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:
As far as i understand UITableView is looped for every Cell in the storyboard, and it is supposed to return cell.
So, whats going on here and why does the cell return nil, or doesnt return at all ?
The only difference is that they are static tables, and not prototypes.
If you are using Storyboards and iOS6 and your view controller is a UITableViewController, you will always get a cell if your cell identifier is present in your storyboard. Checking for cel == nil is the old way to do it.
Are you sure you have a custom cell in your storyboard with the "Cell" identifier?
Also, use this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
If you look in the UITableView.h file you will find:
// newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
Where is you create your cell ??
You should add after:
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
such code (or something another initializer):
if (cell == nil) {
cell = [[UITableViewCell alloc] init];
}
Try this at the beginning of your method:
- (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
];
}
I am using a TableView xib and all the delegates and datasource seem to be running fine.
If I set self.textLabel.text, it displays the generic number of tableviews correctly, but I need to have my custom TableViewCell showing.
I created a HistoryCell.xib that has just a tableviewcell in it.
I created a UITableViewCell class "HistoryCell.h/HistoryCell.m" and it is set as the file owner of HistoryCell.xib.
I connected the UILabels to the HistoryCell.h
UILabel statusLabel
UILabel nameLabel
UILabel timeLabel
In my main ViewController class int he cellForRowAtIndexPath
I am putting in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"historyCellType";
HistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[HistoryCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.nameLabel.text = #"Donald Duck";
return cell;
}
What am I doing wrong?
Thanks!
You should register the nib like this (probably in viewDidLoad):
[self.tableView registerNib:[UINib nibWithNibName:#"HistoryCell" bundle:nil ] forCellReuseIdentifier:#"historyCellType"];
Then in your cellForRowAtIndexPath method, use this new way where you don't need the if cell == nil clause:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
HistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:#"historyCellType" forIndexPath:indexPath];
cell.nameLabel.text = #"Donald Duck";
return cell;
}
You need to deserialize the actual XIB data:
HistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *cellnib = [[NSBundle mainBundle] loadNibNamed:#"HistoryXIBName" owner:self options:nil];
cell = (HistoryCell *)[cellnib objectAtIndex:0];
}
Otherwise it's just using a "Default" cell.
EDIT: Also, if you are using storyboards, dynamic cell prototypes remove the need to create cells from NIB files (in case that's an option for you.)
EDIT The 2nd:
You can try this as well (this assumes you are using ARC):
HistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
HistoryCell *aNewCell = [[HistoryCell alloc] initWithNibName:#"HistoryXIBName" bundle:nil];
cell = (HistoryCell *)*aNewCell.view;
}
There's another method using outlets to your cell in the containing view's XIB file that's a bit more involved that I used to use when iOS4 was current. If the edited version isn't' working for you, I'll dig out an old project and remember how I did it.
When you use tableViewCell with xib, while instantiation load from xib.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"historyCellType";
HistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:#"HistoryCell"
owner:nil
options:nil]lastObject];
}
cell.nameLabel.text = #"Donald Duck";
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellidentifier=#"cell1";
customcell *cell =
(customcell*)[tableView dequeueReusableCellWithIdentifier:cellidentifier];
if (cell==nil) {
[tableView registerNib:[UINib nibWithNibName:#"Customcell" bundle:nil]
forCellReuseIdentifier:cellidentifier];
cell =
(customcell*)[tableView dequeueReusableCellWithIdentifier:cellidentifier
forIndexPath:[NSIndexPath indexPathForItem:indexPath.row
inSection:indexPath.section]];
}
return cell;
}