I have a subclass of UITableViewCell with a xib that I want to use as my table view cell. I need to modify the cell's properties on a cell by cell basis. Here is my code. The NSLog reveals that the properties are changed correctly, but when I run the app, the usernameLabel stays the same as the placeholder in the xib file. I'm grateful for any help and happy holidays.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"SimpleTableItem";
// ActivityCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
LiveCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"LiveCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
if (dataLoaded == YES) {
cell.usernameLabel = [[UILabel alloc] init];
NSLog(#"Data Cell Loaded");
PFObject *liveObject = [tableData objectAtIndex:indexPath.row];
cell.usernameLabel.text= liveObject[#"Name"];
NSLog(#"Name Label: %#", cell.usernameLabel.text);
return cell;
}
else {
return cell;
}
}
Consider this code:
cell.usernameLabel = [[UILabel alloc] init];
NSLog(#"Data Cell Loaded");
PFObject *liveObject = [tableData objectAtIndex:indexPath.row];
cell.usernameLabel.text= liveObject[#"Name"];
NSLog(#"Name Label: %#", cell.usernameLabel.text);
return cell;
You made a label and set its text, but so what? You never put it into the interface of the cell. So the label comes into existence, its text is set, and it then vanishes in a puff of smoke.
If the cell already has a usernameLabel in its interface, then it is wrong to replace it with this new one that is not in the interface. If it doesn't already have a usernameLabel, then you need to put this one in the interface. Either way, this code is silly.
Related
I am new to developing. i have some experience but i'm not great at it (yet). I'm working on this tableview app which shows data. I want to show that data in a custom cell. But i don't know how to do that.
This is the code i use for my tableview:
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HistoryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"HistoryViewTableCell"];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"HistoryViewTableCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
NSDictionary * tempDictionary = [tableData objectAtIndex:indexPath.row];
cell.textLabel.text = [tempDictionary objectForKey:#"PickupAddress"];
return cell;
}
I need to show this line of code in my custom cell.
cell.textLabel.text = [tempDictionary objectForKey:#"PickupAddress"];
I already made a class and a xib file for the custom cell
This may solve the problem:
HistoryTableViewCell *cell = (HistoryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"HistoryViewTableCell"];
your written kind of code will not work. if you are using custom XIB than add a UILable in the xib. and than assign them tag number.
now from ViewController do the following:
write this after #implementation
enum {
CELL_TITLE = 2,
CELL_SUBTITLE_1 = 3,
};
Load the Custom XIB File in cellforrowatindexpath method.
// Get table View Cell
static NSString *CellIdentifier = #"customCell";
UITableViewCell *cell = [atableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib;
nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (UITableViewCell *) [nib objectAtIndex:0];
}
Now Add text on Lable with the below methods;
UILabel *titleLable = (UILabel *) [cell.contentView viewWithTag:CELL_TITLE];
titleLable.text = #"This is your text";
I have a new project where I had to drag a prototype cell to a existing table view. I then
added some labels to the prototype cell with appropriate tags
set a identifier for the cell
and then in my tableview delegate when I get the delegate callback :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"myCustomCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel *nameLabel = (UILabel *)[cell viewWithTag:11];
I see that nameLabel is nil. I have double checked and tripled checked the tag and reusable identifier with no luck. In the storyboard, I see that the tableview has the pro type cell as its cell with the contentView showing my labels. What am I missing?
Do you ever create a new cell in the if (cell == nil) branch? If yes, you are creating a regular UITAbleViewCell there. Do not expect any custom lable there, because you don't load it from any nib file nor from the storyboard.
Of what type is the cell object? NSLog it or have a look in the debugger which type is actually created.
You are allocating UITableViewCell which don't contain your custom label. If you have created a View using Storyboard then you should allocate that view using following method.
You can create a Utility method to get Class instance from NibName
+ (id)loadNibNamed:(NSString *)nibName ofClass:(Class)objClass
{
if (nibName && objClass)
{
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:nibName
owner:nil
options:nil];
for (id currentObject in objects )
{
if ([currentObject isKindOfClass:objClass])
return currentObject;
}
}
return nil;
}
Use this in your code like
CustomViewCell *cell = (CustomViewCell *)[tableView dequeueReusableCellWithIdentifier:#"CustomViewCell"];
if (cell == nil)
{
cell = [Utility loadNibNamed:#"CustomViewCell" ofClass:[CustomViewCell class]];
}
cell.yourLabel.text = #"Dummy Text";
Hopefully this will help you.
Hello I'm having a little bit of trouble with something I'm working on. I have a static TableView with sections and I'm trying to get my text to be positioned in a certain spot so I have a ui label linked to a uitableviewcell. But for some reason It's not working. If you have any ideas on why I'm having trouble with this that would be great. I'm also a bit new to iOS development, just putting that out there.
TableViewController.m:
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
int row = [indexPath row];
if (indexPath.section==0)
cell.textLabel.text = _1[row];
if (indexPath.section==1)
cell.textLabel.text = _2[row];
if (indexPath.section==2)
cell.textLabel.text = _3[row];
if (indexPath.section==3)
cell.textLabel.text = _4[row];
if (indexPath.section==4)
cell.textLabel.text = _5[row];
if (indexPath.section==5)
cell.textLabel.text = _6[row];
if (indexPath.section==6)
cell.textLabel.text = _7[row];
if (indexPath.section==7)
cell.textLabel.text = _8[row];
return cell;
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
#end
TableCell.h:
#import <UIKit/UIKit.h>
#interface TableCell : UITableViewCell
#property (strong,nonatomic) IBOutlet UILabel *TitleLabel;
#end
replace this line
cell.textLabel.text = _1[row];
with
cell.TitleLabel.text = _1[row];
this line is not needed anymore
if (cell == nil) {
cell = [[TableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
in case TableCell is with xib, then you need to load it.
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TableCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
cell.TitleLabel.text = _1[row];
return cell;
you should check this
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier
method to tell the table view how to create new cells. If a cell of the specified type is not currently in a reuse queue, the table view uses the provided information to create a new cell object automatically. if you previously registered a class or nib file with the same reuse identifier, the class you specify in the cellClass parameter replaces the old entry (Apple Document)
in your viewDidLoad method
[self.tableView registerClass:[TableCell class]
forCellReuseIdentifier:#"CellIdentifier"];
I have a custom UIView subclass Leaderboard which itself contains a tableview tblLeaderboard. The interface was created with a xib. Additionally, I have a UITableViewCell subclass LeaderboardCell which also has a xib. I'm having trouble registering the cell in the tableview.
Here's what I tried, first I registered the nib with the tableview:
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
leaderInfo = [NSMutableArray array];
tblLeaderboard.dataSource=self;
[tblLeaderboard registerNib:[UINib nibWithNibName:#"LeaderboardCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"leaderboardCell"];
}
return self;
}
Then when initializing the cell I have:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"leaderboardCell";
LeaderboardCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[LeaderboardCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
//ADDED THIS IN CASE DEFAULT CELL WAS LOADED
cell.textLabel.text = [[leaderInfo objectAtIndex:indexPath.row] objectForKey:#"name" ];
cell.name.text = [[leaderInfo objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.score.text = [[[leaderInfo objectAtIndex:indexPath.row] objectForKey:#"score"] stringValue];
return cell;
}
The cell doesn't load the nib. It just makes a custom cell (the default cell loads the name and score properly, so I know the datasource is working fine).
I'm not sure if I'm getting in trouble here for using a UIView and not a ViewController to control my UITableView?
I don't really have alot of experiences with xibs, but in my old project I did it this way:
static NSString *leaderBoardIdentifier = #"leaderboardCell"; //cell identifier same name as identifier in xib cell's attribute inspector
LeaderboardCell *cell = (LeaderboardCell *)[tableView dequeueReusableCellWithIdentifier:leaderBoardIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:leaderBoardIdentifier owner:self options:nil];
cell = [nib objectAtIndex:0];
}
I have my cell's xib file with h/m files. In my .h I've just connected elements from xib.
initWithStyle and setSelected methods in cell class have default code in them.
Here's what I am trying to do ultimately. I want to display a menu of items in a UITableView, but dynamically, so that the type of item displayed determines the custom cell view loaded. For example, let's say the menu item type is 'switch', then it will load a nib named 'switch.xib' and the state will be on/off depending on that particular menu item's value. There may be 5 items that are "switch" type, but different values. So I want to use the same xib for each one, but 5 instances.
So, long way around to the question. When I load the cell view from the nib, I would think it would need unique reuse identifiers for the dequeue for when it scrolls back on the screen, right? (Unique for each instance, i.e. each menu item.) In the UITableViewCell in Interface Builder, I see where I can set a reuse identifier property, but I want to set it at run time for each instance of the switch. For example, Menu Item #1 is a switch, #2 is a text field, #3 is a switch, etc. So #1 and #3 both need unique cell ID's to dequeue.
Here's what my cellForRowAtIndexPath looks like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Cells are unique; dequeue individual cells not generic cell formats
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
ITMenuItem *menuItem = [menu.menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// Load cell view from nib
NSString *cellNib = [NSString stringWithFormat:#"MenuCell_%#", menuItem.type];
[[NSBundle mainBundle] loadNibNamed:cellNib owner:self options:nil];
cell = myCell;
self.myCell = nil;
}
// Display menu item contents in cell
UILabel *cellLabel = (UILabel *) [cell viewWithTag:1];
[cellLabel setText:menuItem.name];
if ([menuItem.type isEqualToString:#"switch"]) {
UISwitch *cellSwitch = (UISwitch *) [cell viewWithTag:2];
[cellSwitch setOn:[menuItem.value isEqualToString:#"YES"]];
}
else if ([menuItem.type isEqualToString:#"text"]) {
UITextField *textField = (UITextField *) [cell viewWithTag:2];
[textField setText:menuItem.value];
}
return cell;
}
You can set the reuse identifier in the nib file. So for switch.xib you would use 'switch' as the reuse identifier. Then just change
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.row];
to
NSString *CellIdentifier = menuItem.type;
assuming that menuItem.type is 'switch'
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
TextFieldFormElement *item = [self.formItems objectAtIndex:indexPath.row];
cell.labelField.text = item.label;
return cell;
}
For my idea, if your types are not too much design each cell in different xib and swift file. Mainly for performance issues.
If not possible to dequeue, give them different identifier. You can register more than one identifier for tableview or collection view (one of our apps using 12 different cells this way.)
But handling IBActions will be little messy this way.
Your custom cell from xib file can be loaded in a way like this. The xib file name is the same as the cell class name and the reuse id.
- (YourCell *)tableView:(UITableView *)_tableView getCellWithId:(NSString *)cellId
{
YourCell *cell;
/* Cell id and xib have the same name. */
cell = [_tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellId owner:self options:nil];
cell = [nib objectAtIndex:0];
}
return cell;
}