Creating a Custom Table Cell, Cannot Access Property - objective-c

IMPORTANT EDIT: I posted the wrong error code, like an idiot. I was posting the error for an attempt I had previously made to fix the issue, instead of the first error. Disregard my dumbness, please.
I'm creating a Facebook Feed app in Xcode, and I'm running into trouble in the creation of custom cells for a table. I'm trying to assign values to two UILabels on the custom cell, and it's giving me the error "No visible #interface for 'JSONFeedItemCell' declares the selector 'nameLabel'". My code is as follows:
Master View Controller
- (void)viewDidLoad
{
UINib *nib = [UINib nibWithNibName:#"JSONFeedItemCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:#"JSONFeedItemCell"];
... // other stuff, not relevant
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
JSONFeedItemCell *cell = [tableView dequeueReusableCellWithIdentifier:
#"JSONFeedItemCell"];
NSDictionary *p = [[[JSONFeedItemStore sharedStore] allItems]
objectAtIndex:[indexPath row]];
[[cell nameLabel] setText:#"The Name"];
return cell;
}
Cell Class
#import <Foundation/Foundation.h>
#interface JSONFeedItemCell : UITableViewCell
{
}
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UILabel *detailLabel;
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#end
Let me know if you need any additional information or code, I'd be happy to provide it.

Two things: you have to make sure.
#import "JSONFeedItemCell.h" //in your mainViewController.h
And, as Wolfgang Schreurs suggested, typecast the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
JSONFeedItemCell *cell = (JSONFeedItemCell *)[tableView dequeueReusableCellWithIdentifier:
#"JSONFeedItemCell"];
NSDictionary *p = [[[JSONFeedItemStore sharedStore] allItems]
objectAtIndex:[indexPath row]];
[[cell nameLabel] setText:#"The Name"];
return cell;
}
EDIT: since you don't use custom setters/getters you have to synthesize the properties
in JSONFeedItemCell.m
#synthesize imageView;
#synthesize detailLabel;
#synthesize nameLabel;
Compiler should warn you if you forgot to do that but with all the possible compiler settings you never know.

Do you maybe have something like a , I call it, circle import? Xcode gets messed up when you have 2 classes which imports each other. Xcode displays sometimes 'random' errors like this. And sometimes helps to clean and organize project, and restart pc. I have actually no idea why, but it helps sometimes.

Related

custom uitableviewcell will not display label texts

And the value of the labels are null as well.
I'm not really sure what's going on.
These are my classes/codes
#interface CustomEventCell : UITableViewCell{
}
#property (nonatomic, weak) IBOutlet UILabel *participant1label;
#property (nonatomic, weak) IBOutlet UILabel *participant2label;
#property (nonatomic, weak) IBOutlet UILabel *status;
#end
Event model is
#interface Event : NSObject{
}
#property NSNumber *matchId;
#property NSString *participant1, *participant2,
-(id)init;
#end
this is the tableview that fills up the cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EventCell";
CustomEventCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[CustomEventCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// events is a NSMutableArray with Event instances
Event *event = [events objectAtIndex:indexPath.row];
cell.participant1label.text = event.participant1;
return cell;
}
Here's my setup
I must be missing something as I have another uitableview and it populatees the custom without problems. I compared them and they're identical. I even tried going back to the regular label and it would fill that up but not this custom one.
EDIT:
Modified the wrong copied code.
I wrote a simple little test app attempting to replicate what you want to see working. I have made it available here using Storyboards. If you cannot figure it out from this, then perhaps you can take the test app and modify it so that it replicates the bad behavior you are seeing.
My best guess as to what might be going on is that when you initialize your cell, it is not connected to a view in a xib.
Try setting a breakpoint at:
cell.participant1label.text = event.participant1;
and verify that cell.participant1label is not nil by doing:
NSLog( #"cell.participant1label: %#", cell.participant1label );
I had a small bug in which none of my custom labels were showing up and cell.participant1label was nil. The cause was that I had not set the Identifier for the custom table view cell to 'EventCell'. So, I might suggest rechecking that and making sure the identifier really does match between your code and the XIB.

Creating a custom UITableViewCell

I'm trying to create a custom UITableViewCell.
From XCode 4.6 interface builder, I've set the Style property of the cell to Custom. And added controls to the cell using drag and drop. 2 UILables and a UIButton. It looks like this.
I created a separate class deriving from UITableViewCell to assign the properties of the 3 UI elements and make the changes there. I've set the cell's custom class as DashboardCell from the Identity Inspector as well.
DashboardCell.h
#import <UIKit/UIKit.h>
#interface DashboardCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *numberOfMails;
#property (weak, nonatomic) IBOutlet UILabel *mailType;
#property (weak, nonatomic) IBOutlet UIButton *numberOfOverdueMails;
#end
DashboardCell.m
#import "DashboardCell.h"
#implementation DashboardCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.numberOfOverdueMails setBackgroundColor:[UIColor colorWithRed:244/255.0f green:119/255.0f blue:125/255.0f alpha:1.0f]];
[self.numberOfOverdueMails setTitle:#"lol" forState:UIControlStateNormal];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
In the TableViewController, I have modified the following method to return my custom cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
DashboardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[DashboardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
My problem is even though the custom button shows up, the changes I've done (changing the background color of the button, changing the title of one UILabel) aren't showing up. What seems to be the mistake here?
The method initWithStyle:reuseIdentifier: will not be called because you're using interface builder to create a cell.
You can set the background color and title by overriding the method awakeFromNib.
You can also set these in the method tableView:cellForRowAtIndexPath:
If you get your cell from a xib or storyboard, dequeueReusableCellWithIdentifier:forIndexPath: will always return a cell -- if one exists it will reuse it, if not it will create one from the template in IB. Therefore, your if(cell ==nil) clause will never be satisfied, and in fact is no longer needed. If you want to use an init method, then use initWithCoder:

Can't reload Table View in tab bar controller

Hi I have a tab tab controller and my first tab includes a view with:
3 text fields
a submit button
a tableView
Once I fill in the text fields I click submit and it adds the information to my managedObjectContext which is an sqlite database (CoreData).
As soon as I click submit I want the tableView to reload to include the added object. Currently my tableView will display the data in the database but it will only add the new row when I stop and re-run the simulator
This is the code for when the add button is tapped, it is here that I can't get the reload tableView working because it says tableView is an undeclared identifier, what have i missed?
-(IBAction)addButtonTapped:(id)sender {
NSLog (#"Add Button Tapped");
NSLog(#"Adding %# units of item code %# at $%# each",quantityTextField.text,productTextField.text,priceTextField.text);
Products_MarketAppDelegate* delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext* managedObjectContext = delegate.managedObjectContext;
NSManagedObject* newProduct;
newProduct = [NSEntityDescription insertNewObjectForEntityForName:#"Product" inManagedObjectContext:managedObjectContext];
[newProduct setValue:productTextField.text forKey:#"itemCode"];
[newProduct setValue:quantityTextField.text forKey:#"quantity"];
[newProduct setValue:priceTextField.text forKey:#"price"];
if ([managedObjectContext hasChanges])
NSLog(#"Managed Object Changed");
NSError* error;
[managedObjectContext save:&error];
// Insert Reload Table Code Here
// ** I have tried the following and it gives an error "Use of undeclared identifier 'tableView'"
//[tableView reloadData];
//[self.tableView reloadData];
}
As you can see below I have added the UITableViewDelegate & UITableViewDataSource in the header file. I have also hooked up the tableview in IB so that the delegate and datasource connections are linked to file's owner.
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#interface FirstViewController : UIViewController
<UIApplicationDelegate, UITableViewDataSource,UITableViewDelegate,NSFetchedResultsControllerDelegate>
{
IBOutlet UITextField *productTextField;
IBOutlet UITextField *quantityTextField;
IBOutlet UITextField *priceTextField;
NSMutableArray *items;
NSFetchedResultsController *fetchedResultsController;
}
#property (nonatomic, retain) NSMutableArray *items;
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
-(IBAction)addButtonTapped:(id)sender;
#end
This is the code to fill the tableView which works correctly
#pragma mark TableView
-(NSInteger)numberOfSectionsInTableView: (UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (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] autorelease];
}
// Configure the cell
Product* productItem =[fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%# x %# # $%#",productItem.quantity,productItem.itemCode,productItem.price];
return cell;
}
I have searched for answers on this site and on others but I must be doing something different and the solutions aren't helping me
Your UIViewController does not currently have an instance variable pointing to your tableview. Set one up:
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
Remember to synthesize this in your .m
#synthesize myTableView;
Then in your code you can call
[self.myTableView reloadData];
You might have got confused by looking at code examples that use a UITableViewController instead of a UIViewController. The UITableViewController already has an instance variable called tableView, so your subclass wouldn't need it's own tableView instance variable declared. But you're using a UIViewController, so you must declare a tableView instance variable.
Thanks #MattyG for all your help. At first I wasn't sure if I was going against the norm and thats why it wasn't working.
I ended up solving the problem due to your suggestions & it works perfectly! I used the debugger and found that that although we had created a property for the table I had not created an IBOutlet and linked it in my nib file with:
IBOutlet UITableView *myTableView;
I guess this meant that I was telling myTableView to reload but it wasn't hooked up to my table and thus couldn't use the datasource methods.

How to reload UItableView that is inside UiViewController

I have a UITableView inside UiViewController.
In the same screen, I also have two buttons: Show All vs Show Top 5.
Now based on a selection all/top 5, I have to update table data.
I cant use [tableView reloadData] as I am not using UITableViewController.
This is the first time I am working on an iphone app. So any help is appreciated.
(I used this tutorial to get started http://www.icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/)
Thanks.
Here is a snippet of my code:
.h file
#interface DataViewController : UIViewController {
NSString *showType;
}
#property (nonatomic, retain) NSString *showType;
-(IBAction) showTop: (id) sender;
-(IBAction) showAll: (id) sender;
#end
.m file
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"customCell";
DataCustomCell *cell = (DataCustomCell *) [tableView dequeueReusableCellWithIdentifier:cellID];
if([showType isEqualToString:#"all"])
{
// use this data..
}
else
{
// use some other data..
}
// ....
}
-(IBAction) showNearby: (id) sender
{
self.showType=#"top";
// reload table some way
}
-(IBAction) showAll: (id) sender
{
self.showType=#"all";
//reload table some way
}
Create a UITableView IBOutlet like this
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
in your UIViewController's interface file. Then have that connect to the UITableView in Interface Builder. After synthesizing it in your implementation file, you should be able to access it like this
[self.myTableView reloadData];
Also, since you retained it, you will have to release myTableView in the dealloc method.

Editable UITableView with a textfield on each cell

I am new to the iOS world and I want to know how to make a UITableView with custom cells that look and behave like the one you have when you try to configure some WiFi connexion on your device. (You know the UITableView with cells containing UITextFields with blue font where you set up the ip address and all that stuff... ).
To make a custom cell layout do involve a bit of coding, so I hope that dosen't frighten you.
First thing is creating a new UITableViewCell subclass. Let's call it InLineEditTableViewCell. Your interface InLineEditTableViewCell.h could look something like this:
#import <UIKit/UIKit.h>
#interface InLineEditTableViewCell : UITableViewCell
#property (nonatomic, retain) UILabel *titleLabel;
#property (nonatomic, retain) UITextField *propertyTextField;
#end
And your InLineEditTableViewCell.m could look like this:
#import "InLineEditTableViewCell.h"
#implementation InLineEditTableViewCell
#synthesize titleLabel=_titleLabel;
#synthesize propertyTextField=_propertyTextField;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Here you layout your self.titleLabel and self.propertyTextField as you want them, like they are in the WiFi settings.
}
return self;
}
- (void)dealloc
{
[_titleLabel release], _titleLabel = nil;
[_propertyTextField release], _propertyTextField = nil;
[super dealloc];
}
#end
Next thing is you set-up your UITableView as you normally would in your view controller. When doing this you have to implement the UITablesViewDataSource protocol method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. Before inserting your implementation for this, remember to #import "InLineEditTableViewCell" in your view controller. After doing this the implementation is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
InLineEditTableViewCell *cell = (InLineEditTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"your-static-cell-identifier"];
if (!cell) {
cell = [[[InLineEditTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"your-static-cell-identifier"] autorelease];
}
// Setup your custom cell as your wish
cell.titleLabel.text = #"Your title text";
}
That's it! You now have custom cells in your UITableView.
Good luck!