I've used sqlite in my project and I get ten elements in _mChats (array) successfully. The numberOfRowsInSection method returns 10 but cellForRowAtIndexPath ignores the first few rows and in simulator other elements all display on the same cell,why?
And if I use sections instead of rows to display data,everything becomes normal.
This is my code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_mChats count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VChat *cell = [VChat vChatWithTableView:tableView];
cell.mChat = _mChats[indexPath.section];
return cell;
}
I think its because of this
cell.mChat = _mChats[indexPath.section];
Try this instead
cell.mChat = _mChats[indexPath.row];
This is because Indexpath is a property that has two values inside it,
Eg. IndexPath [section,row] meaning indexpath of something is section number 1, row number 5.
Hope this helps you understand.
This is how your cellForRowAtIndexPath should look like:
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
NSString *cellIdentifier = #"myCell";
UITableViewCell *cell = (UITableViewCell *)[iTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
cell.mChat = _mChats[indexPath.row];
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath
{
VChat *cell = (VChat *)[tableViewdequeueReusableCellWithIdentifier:#"CellIdentifier"];
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"VChat" owner:self options:nil];
if (cell==nil)
{
cell = nib[0];
}
cell.mChat = _mChats[indexPath.row];
return cell;
}
The three delegate method must be implement you have wrote have something wrong. As #Abhinav said the method return cell have some thing wrong.
As the code you showed will create a new cell when a new cell present in the screen. I think the first few rows just because the cell has't be reused.
There is another thing I want to say, if you are using storyboard to build the tableview this method should seems like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// The identifier in storyboard you setted.
static NSString *cellName = #"theCell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellName];
if (dataSource_[indexPath.row]) {
// This method will bind data to view
[cell fillDataWithDict:dataSource_[indexPath.row]];
}
return cell;
}
Related
In a VC I have 2 tableViews - 1 main and other is added in a drop down menu. From drop down menu TableView "ddTableView", I have added 5 cells in Storyboard itself as prototype cells. Each cell contains an image and a Label. Have also set identifier for each cell. Have also set Accessory Type as "Disclosure Indicator" for each cell of ddTableView.
DataSource and Delegate for mainTV is set to the VC and delegate for ddTableView is set the VC. As the rows are added within the storyboard, I didn't set any datasource for ddTableView in my VC. I managed my delegate methods like this :-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView) {
// RETURNS NIL ???
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"CELL Identifier = %#", cell.reuseIdentifier);
return cell;
} else {
}
}
-(void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog (#" CELL Clicked of - %#", cell.reuseIdentifier);
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView)
return 44;
else
return 60;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == ddTableView)
return 5;
else
return [chatMsgsArr count];
}
It does call respective delegate method. For cellForRowAtIndexPath it returns cell as nil. Why so ? And on execution, I don't see any contents of the table view - table is blank. I changed the bg color of image and text color also, but yet nothing is seen on execution.
Why so ? Where I may be going wrong ?
You have to allocate the cell, the first time cellForRowAtIndexPath is called. If the cell is not allocated it would return nil as you are getting right now.
What you need to do is allocate the cell only once, the first time you enter cellForRowAtIndexPath. After that you can reuse it as you have done.
If you are planning to use the default tableViewCell your method should look as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"your_cell_identifier_name";
if (cell == nil)
{
UITableViewCell *cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
}
//write the code to populate your cell with data here
//return the cell object
return cell;
}
Hope this helps! :)
- (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] ;
}
if (tableView == ddTableView) {
NSLog(#"CELL Identifier = %d", indexpath.row);
} else {
NSLog(#"CELL Identifier = %#", [chatMsgsArr objectAtIndex:indexPath.row]);
}
return cell;
}
I'm attaching an image because this is kinda hard to explain, I've also mocked up what I actually want it to look like. I'm going to try to explain it to so that others might find the question.
Maybe you've run up against this before and know a fix?
Here is the image of what I have alongside a mockup of what I want:
On the left, what I have, the items in the table are not separated by separator lines but the empty lines cells are separated. Ideally, the empty cells would not be shown and the table would just end letting the background show and the items in the table would have separators between their cells.
This is the corresponding code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSMutableArray *withoutThing = [NSMutableArray arrayWithArray:self.containerOfLists];
[withoutThing removeObjectAtIndex:indexPath.row];
self.containerOfLists = withoutThing;
[[NSUserDefaults standardUserDefaults] setObject:self.containerOfLists forKey:#"list of lists"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.containerOfLists count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = self.containerOfLists[indexPath.row];
return cell;
}
Ok.
In the Storyboard, select your UITableView, set the Separator to Single Line, or by code with:
[yourTableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
In your code, do somewhere:
[yourTableView setBackgroundColor:[UIColor lightGrayColor]];
Or the gray color you want.
Add this to your datasources methods (as the same level as tableView: cellForRowAtIndexPath):
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [[UIView alloc] init];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5; //return correct number
}
in ViewDidLoad method call:
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
Init cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell)
{
//init the cell!
}
cell.textLabel.text = self.containerOfLists[indexPath.row];
return cell;
}
I don't know what I am doing wrong but the cellForRowAtIndexPath method of table view is getting called only once.
Here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"--->%d",[collaboratoresdata count]);
return [collaboratoresdata count];
}
When my collaboratoresdata array is filled, then I am calling [_collaboratortblView reloadData] to reload the table view.
I am successfully getting 3 in NSLog(#"--->%d",[collaboratoresdata count]); but cellForRowAtIndexPath is getting called only one time.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
// add a placeholder cell while waiting on table data
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
NSLog(#"tableView:%d",[indexPath row]);// i am getting 0 here than after its not calling
return cell;
}
check the height of cell i think thats the issue
please try to set height of cell manually(custom). So, if problem of cell height then it will be resolved. below method set cell height 30 pixels.
#pragma mark- TableView delegate Methods
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 30.0f;
}
im using core data i have an entity called questions whenever i add my question to my table i want them to display the number of the question (kind of like auto increment thing)
can anyone pls help me out
thanks
here is my code if its relevant
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.questionArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
// Configure the cell...
questionObject = [self.questionArray objectAtIndex:indexPath.row];
cell.textLabel.text = questionObject.questionDescription;
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (nil == cell) {
cell = ...; //create a cell instance if it wasn't found in reusable cache
}
// Configure the cell...
questionObject = [self.questionArray objectAtIndex:indexPath.row];
NSString *cellText = [NSString stringWithFormat:#"%d. %#", indexPath.row+1, questionObject.questionDescription];
cell.textLabel.text = cellText;
return cell;
}
If I call reloadRowsAtIndexPaths for the first cell of a section, with previous section empty and the one above not-empty, I get a strange animation glitch (even if I specify "UITableViewRowAnimationNone") where the reloaded cell slides down from the above section..
I tried to simplify the example as much as possible:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0)
return 1;
else if (section == 1)
return 0;
else if (section == 2)
return 3;
return 0;
}
- (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...
cell.textLabel.text = #"Text";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *editedCell = [[NSArray alloc] initWithObjects:indexPath, nil];
//[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:editedCell withRowAnimation:UITableViewRowAnimationNone];
//[self.tableView endUpdates];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Section";
}
Actually you can comment out the last method, but it gives a better understanding of the problem.
You can set values you want to the cell directly, not letting table to reload itself (and thus avoiding any unwanted animations). Also to make code clearer and avoid code duplication lets move cell setup to a separate method (so we'll be able to call it from different locations):
- (void) setupCell:(UITableViewCell*)cell forIndexPath:(NSIndexPath*)indexPath {
cell.textLabel.text = #"Text"; // Or any value depending on index path
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self setupCell:cell forIndexPath:indexPath];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// create cell
// Configure the cell...
[self setupCell:cell forIndexPath:indexPath];
return cell;
}