I have a customTableViewCell that I am trying to set an image and some text on. The cell is created successfully, but the properties are nil. I'm not sure if there is something I'm missing in the .xib, but I just can't figure it out. The outlets are set in the .h of the customViewCell and connected in the .xib
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"socialMediaCell";
CustomSocialMediaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
CustomSocialMediaTableViewCell *tagCell = (CustomSocialMediaTableViewCell*)[tableView dequeueReusableCellWithIdentifier:#"socialMediaCell"];
if (cell == nil) {
cell = [[CustomSocialMediaTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
tagCell = [[CustomSocialMediaTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:#"socialPosts"];
UIImage* image = [UIImage imageWithData:imageData];
cell.socialMediaTextView.text = #"TEXT";
cell.socialMediaImageView.image = image;
return cell;
}
You are referencing the same CustomTableViewCell twice and then you are allocating things to it:
static NSString *cellIdentifier = #"socialMediaCell";
****Declared once here****
CustomSocialMediaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
****Declared a second time here***
CustomSocialMediaTableViewCell *tagCell = (CustomSocialMediaTableViewCell*)[tableView dequeueReusableCellWithIdentifier:#"socialMediaCell"];
Use the first declared cell and remove the second.
Then you are saying if the cell is empty, style it and you have done that twice. Do it once.
if (cell == nil) {
cell = [[CustomSocialMediaTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault];
}
Then you can add and assign the things you need.
I have a feeling that you may have tried to do this a more difficult way by modern methods by creating a .xib for it when you can just select the TableViewCell in your storyboard and set it's class. Then you can ctrl + drag from your UILabel and UIImage to your .h file.
If you do not wish to do this or have not structured it this way ensure that your referenced UILabel and UIImage are connected properly and that you have declared an IBOutlet for both - like so
#property (nonatomic, weak) IBOutlet UILabel * customText;
Edit inside if (cell==nil) with the below code
if (cell == nil) { //Check cell is nil or not
NSArray *nib;
nib = [[NSBundle mainBundle] loadNibNamed:#"CustomSocialMediaTableViewCell"
owner:self options:nil]; //if cell is nil add CustomSocialMediaTableViewCell Xib
for (id oneObject in nib) if ([oneObject isKindOfClass:[CustomSocialMediaTableViewCell class]])
cell = (CustomSocialMediaTableViewCell *)oneObject;
}
Related
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.
I am trying to create a custom table view cell with a xib but when I call:
CustomReferenceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
I get the following:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x7aa59c00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key
Here is my setup:
- (void)viewWillAppear:(BOOL)animated
{
[self.tableView registerNib:[UINib nibWithNibName:#"CustomReferenceTableViewCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"referenceCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"referenceCell";
CustomReferenceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CustomReferenceTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.number.text = #"1";
cell.referenceName.text = #"Name";
cell.reference.text = #"The text of the reference";
return cell;
}
Here is a picture of my connections in interface builder. Also my cellIdentifiers match between class and xib:
I have seen this post here but I still can't seem to get it work.
Help would be greatly appreciated.
Edit
Here is a pic showing setting of custom class. Below that is my initialiser for the tableViewCell:
Here is the header:
#import <UIKit/UIKit.h>
#interface CustomReferenceTableViewCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *number;
#property (nonatomic, weak) IBOutlet UILabel *referenceName;
#property (nonatomic, weak) IBOutlet UILabel *reference;
#end
And here is the implementation:
#import "CustomReferenceTableViewCell.h"
#implementation CustomReferenceTableViewCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
I think you are setting the file owner of the cell to your custom cell which you shouldn't do. The way to get things working for a custom cell is,
In your xib, have a Table View Cell component an populate the contents of the cell in its ContentView.
Make your class CustomReferenceTableViewCell as the Custom Class of that cell component.
Now, do NOT register the cell in your tableview; instead do the following in the cellForRowAtIndexPath when your cell is nil after [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; and then register it:
cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil) {
[self.tableView registerNib:[UINib nibWithNibName:[#"CustomReferenceTableViewCell" ] bundle:nil] forCellReuseIdentifier:cellID];
NSArray *nibContents;
CustomReferenceTableViewCell *cell;
nibContents = [[NSBundle mainBundle]
loadNibNamed:nibName owner:self options:NULL];
NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
NSObject *nibItem = nil;
while ((nibItem = [nibEnumerator nextObject]) != nil) {
if ([nibItem isKindOfClass:[CustomReferenceTableViewCell class]]) {
cell = (CustomReferenceTableViewCell *)nibItem;
}
}
}
This method has been working out for me for the past 8 months. I have no reasons why it could cause a problem to you.
Try to set your static NSString *cellIdentifier = #"referenceCell"; above #interface
And change registerNib place from WillAppear to viewDidLoad. Also you can change cell creating
CustomReferenceTableViewCell *cell = (CustomReferenceTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:#"CustomReferenceTableViewCell" owner:self options:nil] lastObject];
}
Just follow my coding for your app
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"Reuse"];
NSArray *nib=[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
if(cell == nil)
{
cell = [nib objectAtIndex:0];
}
cell.number.text = #"1";
cell.referenceName.text = #"Name";
cell.reference.text = #"The text of the reference";
return cell;
}
Firstly CodingVoldermort's answer helped me get to sort out the issue. I was setting the File's Owner to my custom class which you shouldn't do. This should be left as NSObject.
The reason I thought it needed to be changed was because I couldn't hook up my IBOutlets by holding control and clicking on the tableview image under placeholders and dragging to the appropriate view in the xib.
Instead I needed to go under 'Show the connection inspector' pane and control + click and drag from there to get the connections to work. Then my original posted code would work.
Many thanks for all the responses guys.
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.