I am trying to use custom UITableViewCells defined in IB where there are referencing outlets. I have successfully used the techniques shown in several places in stackoverflow to load and use UITableViewClass when there is no referencing outlet, like below.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TheCellsClass" owner:nil options:nil];
I have a separate file called "TheCellsClass.xib", which has a single UITableViewCell defined with a single UILable called Alabel, "IBOutlet UILabel *Alabel;". If I connect the label to ALabel then I get this error
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x681b360> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Alabel.'
After searching here and the web I understand that this is caused by the fact that "owner:nil" does not define a class with this object:Alabel. I cannot use "owner:self" because that is the UITableViewController, and also does not define "Alabel".
I created a class called "TheCellsClass" as a sub class of "UITableViewCell" that does define Alabel, see below;
Then used:
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TheCellsClass" owner:cell options:nil];
I still get the same error. So, can anyone point out the error of my ways? :-)
I only way I can think to fix this is to remove all referencing outlets and connect
them using code
Subclass header :
#import <UIKit/UIKit.h>
#interface TheCellsClass : UITableViewCell {
IBOutlet UILabel *Alabel;
}
#property (strong, nonatomic) UILabel *Alabel;
#end
Subclass body:
#import "TheCellsClass.h"
#implementation TheCellsClass
#synthesize Alabel;
#end
In the table view controller
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I am using:
TheCellsClass* cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TheCellsClass" owner:cell options:nil];
A zip of a sample project is here http://www.proaa.com/tryout.zip
Suggestions? Requests for more info?
Any help appreciated.
Geoff
Three things:
Remove TheCellClass from DetailViewController.xib
ALabel is linked to File's Owner in TheCellsClass - link it instead to TheCellsClass in the Objects section. Also consider renaming ALabel - it is standard to name instance variables beginning with a lowercase letter.
In MasterViewController, change
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TheCellsClass" owner:cell options:nil];
to
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TheCellsClass" owner:nil options:nil];
After these three changes, your custom TableViewCell appeared in the simulator. Also consider renaming TheCellsClass to something that hints at what it's subclassing, like MyCustomTableViewCell.
Without looking at your project, one thing comes to mind. If you have an instance of your custom cell in our nib, and then you have this label in that same nib, then the connection should be from the UILabel to the custom cell. You shouldn't be connecting it to file's owner, at least from the way you've described what you're trying to achieve.
Hope that helps.
Related
NIB file is loaded successfully in my scrollView but sounds like it's class is totally ignored as if the xib is not associated with it, i checked that by accessing the class direct and its working fine showing all the NSLogs in viewDidLoad and UILable.text = # ...etc.,
But after loading the same xib i can't see but a dead interface
Asking after a whole day of searching on this issue. Thanks in advance for you super guys
Loading Nib by: ( in Setting.m )
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"SettingProfile" owner:self options:nil];
UIView *settingA = [nibViews objectAtIndex: 0];
[ScrollView addSubview:settingA];
SettingProfile.h
#class SettingProfile;
#interface Setting UIViewController {
SettingProfile *SettingProfile;
}
#property (nonatomic, retain) SettingProfile *settingProfile;
It looks like you are loading the Nib into a UIView which may not be the result you are looking for... I use the nib loading in my Table View... Perhaps this snippet will help you
OfferCell *cell = nil;
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"OfferCell" owner:self options:nil];
cell = (OfferCell*)[nib objectAtIndex:0];
I then do whatever I want with by cell.
Including add it to the tableView...
When I retrieve it I cast it into the OfferCell object again.
Partially solved, to those whom facing the same problem just add the loaded Nib name in the owner:
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"SettingProfile" owner:#"SettingProfile" options:nil];
UIView *gridView = [nibViews objectAtIndex: 0];
[ScrollView addSubview:gridView];
Still trying to connect the outlets in the loaded Nib/class correctly, i know connecting it with the same file owner is wrong causing app crash.
I am getting this error:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x5a37750> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key destination.'
Following is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ReservationCell";
ReservationCell *cell = (ReservationCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ReservationCell" owner:nil options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (ReservationCell *) currentObject;
break;
}
}
}
//cell.origin.text = [[data objectAtIndex:indexPath.row] origin];
//cell.destination.text = [[data objectAtIndex:indexPath.row] destination];
//cell.time_range.text = [[data objectAtIndex:indexPath.row] time_range];
return cell;
}
Here is the ReservationCell.h
#interface ReservationCell : UITableViewCell {
UILabel * origin;
UILabel * destination;
UILabel * time_range;
}
#property (nonatomic, retain) IBOutlet UILabel * origin;
#property (nonatomic, retain) IBOutlet UILabel * destination;
#property (nonatomic, retain) IBOutlet UILabel * time_range;
#end
Here's how I wired it up:
For someone, who already reached to this thread and not able to figure out the solution like me, here is the quick solution to this problem:
In interface builder you linked your IBOutlets from File's Owner when you should link them from the cell view. This is why you are getting the errors.
Good Luck!!!
This problem happen when in the interface builder for the CustomCell nib, the File's Owner custom class is set to your CustomCell class.
File's owner custom class should be set always UITableViewCell.
Table view object custom class should be set to your CustomCell class.
Also you need to initialize it with Nib name of your tableview cell.
Example (NotificationCell is my custom cell class):
http://i42.tinypic.com/29pw0a8.png
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ReservationCell"
owner:nil
options:nil];
Is setting the Files Owner to nil. So you can't wire any of your labels to that. Instead, make sure the class of the cell is ReservationCell and its outlets are connected to the labels.
My exception was 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key (and name label which I had on the CustomCell, I got this error only when I added something in CustomCell e.g. label)
Solution problem my friend gave me great advice add MyCustomCell.m add to the ProjectSettings -> Build Phases -> add MyCustomCell.m file
In my case I had added the interface for the cell to the header file but did not have an implementation in the .m file. Simply adding an empty implementation (as below) for the class to the .m file fixed the problem.
#implementation myTableViewCell
#end
Surprised this has not been listed as an answer as this has bitten me several times in the past. Hope this helps someone!
I had this problem when I had duplicated a prototype cell in storyboard and deleted one of the outlets in the cell. It left a reference to the outlet but not connected to anything. Right-click on the prototype cell and look for one of those yellow warning markers.
I am trying to build a custom table view using a cell that I built in IB. I am getting a strange error:
<BroadcastViewController 0x4b4f5f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key postText.
Everything is wired up correctly in IB to the cell controller. Not really sure why this is happening.
This is what my cellForRowAtIndexPath looks like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the folder object of interest
Broadcast *messageAtIndex = [self.messages objectAtIndex:indexPath.row] ;
static NSString *CellIdentifier = #"BroadcastTableViewCell";
static NSString *CellNib = #"BroadcastTableViewCell";
BroadcastTableViewCell *cell = (BroadcastTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//ERRORING ON THIS LINE...
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (BroadcastTableViewCell *)[nib objectAtIndex:0];
}
cell.postText.text = messageAtIndex.replyText;
cell.authorName.text = messageAtIndex.postCreatorFirstName;
cell.postDate.text = messageAtIndex.creationDate;
return cell;
}
Anyone seen this kind of error before? Let me know if you need any more information...
What is really strange is that it complains that the class BroadcastViewController is not KVC compliant to postText.
As far as I can see, postText is a label in your cell, so the IBOutlet for this should be in the BroadcastTableViewCell class. So check out where you've linked the postText label in IB. Also, it can be that you had an IBOutlet in your view controller for this label, you've removed it but you forgot to delete the link in IB. Anyway, there somewhere is your problem. The fact that you have the error on that line is just because it's there you load your NIB, it doesn't have anything to do with the cell itself or with the owner.
Might has something to do with dequeueReusableCellWithIdentifier returning an UITableViewCell*.
I normaly do this:
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier...
CustomCell* acell = (CustomCell*)cell;
Set the owner to nil.
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:nil options:nil];
Ok figured it out. The connections in IB were indeed incorrect. I had them linked to the file's owner as opposed to the actual objects. I am going to give this too Stelian because he directed me to check out the nib. Thanks for all your help!
I am building a simple Navigation-based app using tables.
I have a custom "UITableViewCell" to customize the table cell data attached below.
#interface NewsCell : UITableViewCell
{
IBOutlet UILabel *newsTitle;
}
- (void)setNewsLabel:(NSString *)title;
#end
And then in my RootViewController, I set the text of the label "newsTitle" in "cellForRowAtIndexPath" method as follows.
static NSString *MyIdentifier = #"MyIdentifier";
MyIdentifier = #"NewsCell";
NewsCell *cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"NewsCell" owner:self options:nil];
cell = newsCell;
}
[cell setNewsLabel:#"hello testing"];
return cell;
When I run this, the app runs fine, but I get "NewsCell may not respond to '-setNewsLabel:'" warning.
Please help! Thank you.
In RootViewController.m, you need to `#import "NewsCell.h".
Or, stick #import "NewsCell.h" in your project's PCH (pre-compiled header) file.
The underlying issue is that the compiler only knows about methods that it has previously seen when parsing the header files (or ones in the PCH).
You're creating the nib, but not assigning it to anything. See this question to create it right.
Where does the variable newsCell come from? Is it really of type NewsCell?
if (cell == nil) // 1
{ // 2
[[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil]; // 3
cell = tvCell; // 4
self.tvCell = nil; // 5
} // 6
There's some code from an Apple example of using your own "custom cell XIB" to create cells in a UITableView.
It appears to work... but I think I would do better to actually understand what is being done there.
Why isn't the following assigning the value to something?
cell = [[NSBundle mainBundle] loadNibNamed:#"TVCell" owner:self options:nil];
(In fact, cell and tvCell aren't being used at all.)
Why is line #4 assigning using tvCell when nothing has been put it in at all, yet?
Why is line #5 nulling out the tvCell that I need?
Why is this line using assign, not retain?
#property (nonatomic, assign) IBOutlet UITableViewCell *tvCell;
About the only thing I can't get working correctly is when I put a disclosure-button on my custom cell XIB. Is there a way for me to detect when the user has clicked on it? (Hopefully, without using 100s of TAGs.)
I haven't played with XIBs for cells, but I don't see why you couldn't still use tableView:accessoryButtonTappedForRowWithIndexPath:.