Cell from nib for UITableView preload - ios

At first I had this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DropDownTableViewCell"];
if (!cell) {
NSArray *topLevelObjects =
[[NSBundle mainBundle] loadNibNamed:#"DropDownView"
owner:self
options:nil];
for (DropDownTableViewCell *object in topLevelObjects) {
if ([object class] == [DropDownTableViewCell class]) {
cell = object;
break;
}
}
NSAssert(cell, #"Cell must not be nil");
}
cell.nameLabel.text = [self.dataSource buttonDownPicker:self stringForRowAtIndexPath:indexPath];
return cell;
}
At first moment when I show tableView and tableView cell's starts loading from nib I have UI freezing for a few seconds (caused by loading from nib for EVERY displayed cell). This can be solved by loading cell from nib earlier:
- (void)awakeFromNib {
DropDownTableViewCell *cell = [[[NSBundle mainBundle] loadNibNamed:#"DropDownView" owner:self options:nil] objectAtIndex:0];
}
But this way looks "hacky". Is there more appropriate solution?
Edit according to given answers:
I've tried to use registerNib forCellIdentifier but it didn't LOAD nib, it just BINDING nib with identifier and at first time when tableView appears all cells causing load nib to memory

This is not "hacky" at all. For loading cells from a nib what you usually do is load the nib and then register the cell for reusable identifier of your choosing. For instance in one of my projects I have a view controller with a table view. In the view did load I call:
[[NSBundle mainBundle] loadNibNamed:#"ChannelListCell" owner:self options:nil];
[self.channelListTableView registerNib:[UINib nibWithNibName:#"ChannelListCell" bundle:nil] forCellReuseIdentifier:#"channelListCell"];
Then in the cell for row at index path:
cell = [tableView dequeueReusableCellWithIdentifier:#"channelListCell" forIndexPath:indexPath];
In your case the dequeued cell is always nil since you did not register it.

Try like this.....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UINib *nib = [UINib nibWithNibName:#"" bundle:nil];
[self.tblview registerNib:nib forCellReuseIdentifier:#"DropDownTableViewCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DropDownTableViewCell"];
return cell;
}

You can register your class first like bellow in your viewDidLoad. It make faster and better
[self.tableViewObject registerClass: [DropDownTableViewCell class]forCellReuseIdentifier:#"DropDownTableViewCellIdentifier"];
And please add following method in your DropDownTableViewCell.m file
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"DropDownTableViewCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
self = [topLevelObjects objectAtIndex:0];
return self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier=#"DropDownTableViewCellIdentifier";
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
//Access all cell properties here.
return cell.
}
Please refer https://stackoverflow.com/a/30954273/914111 for better knowledge.

Related

UITableViewCell created from XIB doesn't show content

I have created a UITableVIewCell from a XIB file. However, it doesn't get displayed on the application.
Here's my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tablev registerClass:[MCell class] forCellReuseIdentifier:#"c"];
MCell *cell = (MCell*)[tableView dequeueReusableCellWithIdentifier:#"c"];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MCell" owner:self options:nil];
cell = (MCell *)[nib objectAtIndex:0];
}
cell.la.text=#"This is from custom cell";
//cell.textLabel.text=#"from label";
return cell;
The text This is from custom cell doesn't get displayed. But, cell.textLabel.text=#"from label"; gets executed perfectly and displays the text. I think my UITableViewCell hasn't got initialised in the code. Can someone look into this ?
You have to put this method
[self.tablev registerNib:[UINib nibWithNibName:#"MCell"
bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"c"];
in your viewDidLoad: or awakeFromNib: if you are using tableView in an UIView XIB file or any initializing method where you initialize your other properties and variables.
and in your tableView:cellForRowAtIndexPath: method, do the following
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MCell *cell = (MCell*)[tableView dequeueReusableCellWithIdentifier:#"c"];
cell.la.text=#"This is from custom cell";
//cell.textLabel.text=#"from label";
return cell;
}
You might need to register your nib file:
[self.tableView registerNib:[UINib nibWithNibName:#"MCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"c"];

iOS: UITableViewCell subclassing with nib, into UIView (not view controller) subclass

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.

iOS: Custom UITableViewCell from nib without a reuseIdentifier?

I have a custom UITableViewCell that's loaded from a nib. I can pull this into my app with a reuseIdentifier by performing the following steps:
1) Set the reuse identifier in the Nib as "CustomCellIndentifier"
2) Register the nib:
[[self tableView] registerNib:[UINib nibWithNibName:#"CustomCell" bundle:nil] forCellReuseIdentifier:#"CustomCellIndentifier"];
3) Return the cell in tableview:cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCellIndentifier"];
return cell;
}
My question is, how can I return a cell WITHOUT a reuse identifier? I have a small table and I don't want the cell to be reused (it messes up some subviews I have in the cell if I scroll).
I've tried a combination of setting the above 3 reuse identifiers to nil and they all generate errors.
I've also tried this below, but the cell contents reset if I scroll past the cell and I get an error message "no index path for table cell being reused":
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}
I think this is not a good way, but as per your requirement Use this:
Write the init method in your CustomCell class
- (id)init
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"QuestionOptionCell" owner:self options:nil];
CustomCell *theEditView = [nibObjects objectAtIndex:0];
self = theEditView;
theEditView = nil;
return self
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [[CustomCell alloc] init];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
return cell;
}

Getting EXC_Bad_Access while scrolling tableview

I am getting EXC_BadAccess error message while i am scrolling tableview.
the following is the code i have done in cellForRowAtIndexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier=#"customCellHistory";
customCellHistory *cell=(customCellHistory*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle]loadNibNamed:#"customCellHistory" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]] ) {
cell=(customCellHistory*)currentObject;
break;
}
}
}
cell.lb11.text=[cellArray1 objectAtIndex:indexpath.row];
cell.lbl2.text=[cellArray2 objectAtIndex:indexpath.row];
return cell;
}
I can sense the problem is arising due to some mistake in the above code.
I used CustomCell in the above code to display a customized cell.
can anyone tell me what wrong have i done in this code
Hey try the following code, dont forget to set the cell identifier in you custom XIB to customCellHistory
At the top
#import "customeCellHistory.h"
then
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"customCellHistory";
customCellHistory *cell = (customCellHistory *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"customCellHistory" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.lb11.text=[cellArray1 objectAtIndex:indexpath.row];
cell.lbl2.text=[cellArray2 objectAtIndex:indexpath.row];
return cell;
}
The problem seems to arise from the strange loop you have. Use the last object method to set cell from the nib.
You are reusing a cell and then changing the cell in your loop which probably leads to a cell not existing where you are looking.
if (cell == nil) {
NSArray *topLevelObjects=[[NSBundle mainBundle]loadNibNamed:#"customCellHistory" owner:self options:nil];
You don't need that code. Just register the nib with the table view, earlier on:
[self.tableView registerNib:[UINib nibWithNibName:#"customCellHistory" bundle:nil]
forCellReuseIdentifier:#"customCellHistory"];
Now when you call dequeueReusableCellWithIdentifier, the nib will be loaded and the cell will be delivered, if there is no spare cell in the reuse pile. This ensures that you consistently have a cell and that it is the right kind of cell. Use the methods the framework gives you.

Custom code for UITableViewCell

I would like to know where to enter custom code to change the value of a Label property for a UITableViewCell.
I am not sure how this is loaded, as I have put an NSLog in the ViewDidLoad and (id)initWithStyle instance methods but neither write to the log.
I have setup a NIB and custom class all correctly linked, and the Label is linked as a property and no longer causes an error. But I am unable to setText.
This is how the custom cell is called:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
LeftMenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"LeftMenuTableViewCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (LeftMenuTableViewCell*)view;
}
}
}
return cell;
}
This is the code in the IMP file for the LeftMenuViewCell class.
-(void)viewDidLoad {
displayName.text = [self.user objectForKey:#"displayName"];
I can set the displayName to a string and this does not change either. If I add an NSLog to the viewDidLoad for the custom cell class it is not shown, like it is not loaded, but the cell is loaded...?
Without code specifics, I can only give a vague'ish answer.
Your custom cell will need to subclass UITableViewCell, and you need to provide your table with this custom subclass when the data source method tableView:cellForRowAtIndexPath:.
I'd suggest reading up on how cells are added/used with UITableViews:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW1
Let's say that you have custom UITableViewCell with UILabel called testLabel. If your NIB and custom class are properly linked than you can use following code:
MyTableViewCell.h
#interface MyTableViewCell : UITableViewCell
#property (nonatomic, assign) IBOutlet UILabel *testLabel;
#end
cellForRowAtIndexPath in your UITableViewController or UIViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyTableViewCellId";
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"MyTableViewCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
[cell.testLabel.text = [_dataSource objectAtIndex:[indexPath row]]];
return cell;
}
Hope it helps :)
For example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RouteCell *routeCell = [self.tableView dequeueReusableCellWithIdentifier:routeIdentifier];
if (routeCell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RouteCell" owner:nil options:nil];
routeCell = [nib objectAtIndex:0];
}
routeCell.travelTime.text = #"Here you are setting text to your label";
return routeCell;

Resources