Table View's cellForRowAtIndexPath: not being called - ios

For some reason, my table view's cellForRowAtIndexPath:(NSIndexPath *)indexPath method isn't being called. Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
messages = [[NSMutableArray alloc]init];
chatTable = [[UITableView alloc]init];
chatTable.delegate = self;
chatTable.dataSource = self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Called Count %i",messages.count);
return messages.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Was Called");
static NSString *cellId = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
NSDictionary *message = [messages objectAtIndex:indexPath.row];
NSString *mess = [message objectForKey:MSChatMessage];
cell.textLabel.text = mess;
return cell;
}
Here's what I've done:
Linked the datasource and delgate
Linked the IBOutlet for the table view
Set the cell identifier to Cell
Made sure the array was not nil (the log gives the right number)
Tried using a static NSMutableArray, and it worked, but once i went back to my dynamic array it did not
"Was Called" never appears in the log

You initialized message:
messages = [[NSMutableArray alloc]init];
But then you never populated the array.
cellForRowAtIndexPath delegate is called based on the datasource array count.
Make sure the following line:
NSLog(#"Called Count %i",messages.count);
prints a count greater than 0

When you have linked the UITableView from xib or storyboard as IBOutlet. Why are you creating the UITableView again "chatTable = [[UITableView alloc]init]"
Remove this line from the code and try.
Also set the delegate and datasource from the Interface Builder and remove chatTable.delegate = self; & chatTable.dataSource = self;
Also observed that you are creating the message in viewDidLoad which is not proper. Try to print this count of messages, it should not be zero.

i hop these helps..
in .h file..
NSMutableArray * messages;
in .m file..
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialization of NSMutableArray.
messages = [[NSMutableArray alloc]init];
}
and make sure its not nil in here..
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Called Count %i",messages.count);
return messages.count;
}

Related

Recreate a uitableview section dynamically on a uibutton`s click

I need to recreate a UITableView section on a UIButton click. Here is an example for this.
AND in button click it should be created like this.
But i am not able to implement this .
Please Help.
I am just creating a simple UITableView with a textLabel.
Code For cellForRowAtIndexPath is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
Create a integer variable index and property for tableview in .h
#property UITableView *tableView;
Then in -(void)viewDidLoad set index=0;
Now, write a method which is get called when you tap on add button
-(void)newTableView
{
tableView = [UITableView alloc] initWithFrame:CGRectMake(x,y+height*index,width,height)];
//other code related to table
tableView.tag = ++index;
[self.view addSubview:tableView];
}
Use tag in delegate methods
Edit: As you requested to add new section in Table View instead of new table view
You have to first create table view of grouped style
tableView = [UITableView alloc] initWithFrame:(CGRect)frame style:UITableViewStyleGrouped];
Now, When you hit on that add button call a method
-(void)newSection
{
count++;
[tableView reloadData];
}
Then, you have to implement this delegate methods for grouped table view
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"title";
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
//same as your previous code
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//same as your previous code
}
//
// ViewController.m
// DynamicNewSections
//
// Created by J Pulikkottil on 14/07/15.
// Copyright (c) 2015 J Pulikkottil. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic) NSMutableArray *arrayData;
#property (strong, nonatomic) IBOutlet UITableView *tableViewTest;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrayData = [NSMutableArray array];
//section1
[self addSectionArray];
}
- (IBAction)addSection:(UIButton *)sender {
[self addSectionArray];
[self.tableViewTest reloadData];
}
- (void) addSectionArray{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Height",#"label", #"", #"value", nil];
NSArray *arraysection = [NSArray arrayWithObjects:dict, nil];
[self.arrayData addObject:arraysection];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableViewTest.frame.size.width, 45)];
view.backgroundColor = [UIColor yellowColor];
return view;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return [self.arrayData count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [[self.arrayData objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellDetails" forIndexPath:indexPath];
NSArray *arraysection = [self.arrayData objectAtIndex:indexPath.section];
NSDictionary *dict = [arraysection objectAtIndex:indexPath.row];
cell.textLabel.text = [dict valueForKey:#"label"];
cell.detailTextLabel.text = [dict valueForKey:#"value"];
return cell;
}
#end
Try this:
Just have a property (e.g. numberOfSections)
Set it to 1 in viewDidLoad
In the numberOfSectionsInTableView: return self.numberOfSections;
In the IBAction of your UIButton add this code:
self.numberOfSections++;
[self.tableView beginUpdates];
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:self.numberOfSections-1]
withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];

How to access objects inside an array object

I am creating an application for IOS and am struggling with accessing an object inside an array i have made for display on the table view cell.
This is the code i have used to add the object to the array every time the loop cycles through.
for (int i = 0; i < [parsedArray count]; i++) {
HPTBusStops *busStops = [[HPTBusStops alloc] init];
NSArray *informationArray = [parsedArray objectAtIndex:i];
busStops.busStopNumber = [informationArray objectAtIndex:0];
busStops.busStopName = [informationArray objectAtIndex:1];
busStops.latitude = [informationArray objectAtIndex:2];
busStops.longitude = [informationArray objectAtIndex:3];
[self.busStopsHolder addObject:busStops];
}
The HPTBusStops class is obviously custom, and later in the master view controller, i am tring to re-access these properties through the busStopsHolder array, when programming the cell, in this part:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HPTBusStopsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"BusStopCell" forIndexPath:indexPath];
return cell;
}
I am honestly very unsure of how to access the busStops object's properties through the busStopHolder's array.
Any help would be appreciated
Thanks
Hamish
It looks to me like you might have an issue with scope...
You'll need to make "busStopsHolder" a #property of the class containing the for loop and instantiate that class as an instance variable in your Master View Controller.
in your class, say MyInfoClass.h:
#property (strong, nonatomic) NSMutableArray *busStopsHolder;
in MyInfoClass.m:
synthesize busStopsHolder;
Make sure you have initialized your busStopsHolder array in MyInfoClass...
(id) init {
busStopsHolder = [[NSMutableArray alloc] init];
}
Then in your master view controller .h:
#import "MyInfoClass.h"
#interface myMastserViewController : UIViewController {
MyInfoClass *infoClass;
}
Then...
- (void) viewDidLoad {
infoClass = [[MyInfoClass alloc] init];
[infoClass methodToLoadBusStops];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HPTBusStopsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"BusStopCell" forIndexPath:indexPath];
HPTBusStop *busStop = [[infoClass busStopsHolder] objectAtIndex:indexPath.row];
[[cell textLabel] setText:[busStop busStopName]]
return cell;
}
An oversimplified way to do this is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HPTBusStopsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"BusStopCell" forIndexPath:indexPath];
HPTBusStops *busStops = yourSourceArray[indexPath.row];
cell.textLabel.text = busStops.name;
return cell;
}
If your tableView has one section, you can use the tableView's indexPath.row property to determine which index you're dealing with, use that as the index to access the relevant object in your source array, and then customize the cell based on the specific object at that index. In the example code I just assumed there was a name property on the busStops object for example purposes.
Make sure in your numberOfRowsInSection method you set the number of rows as the number of objects in your source array, whatever that is.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return yourSourceArray.count;
}

Populate UI Table View with array of strings

I can't find a simple, concise answer anywhere and I refuse to believe that XCode makes things as hard as other tutorials I've found out there...
Say I have the following array
NSArray* days = [NSArray arrayWithObjects:#"Sunday",#"Monday",#Tuesday",#"Wednesday",#"Thursday",#"Friday",#"Saturday",nil];
I have a UI Table View, table_Days, that I would like to simply show the items from my array. What is the proper way to go about populating my table?
Here's my full explanation, starting with a case extremely similar to yours:
http://www.apeth.com/iOSBook/ch21.html#_table_view_data
So suppose days is stored as an instance variable accessed through a property self.days. Then set self as the table view's datasource and use this code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (!self.days) // data not ready?
return 0;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.days count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"Cell"
forIndexPath:indexPath];
cell.textLabel.text = (self.days)[indexPath.row];
return cell;
}
You should populate your table view using the data source methods. Returning the count of the array for the number of rows.
If you need to detect when a user taps on a cell you can use the delegate methods.
#interface ViewController<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, copy) NSArray *days;
#property (nonatomic, strong) UITableView *tableDays;
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableDays; // Set this up
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
tableDays.delegate = self;
tableDays.dataSource = self;
[self.view addSubview:tableDays];
self.tableDays = tableDays;
self.days = #[#"Sunday", #"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday"];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.days count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.days[indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *day = self.days[indexPath.row];
NSLog(#"Day tapped: %#", day);
}
#end
You should consider using a UITableViewController if you just want to show a table view.
Note that its better practice to use camel case for variables.

Give section index without any section in table view in objective C for sorting single NSArray?

means I want all that records from NSArray starts with 'J' when i tapped on 'J' section title in right side.
Below i give my code in this code i don't want any section i have only one plist
in that i store all the states in india so i now i don't want to any section and when i
tap on any alphabet at that time sorting perform and all that rows which starts with that tapped
alphabet i want. i give example above and code below
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Enter in numberOfRowsInSection method.");
NSLog(#"returning number of rows in a plist.==%d ",test.count);
return test.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Enter cellForRowAtIndexPath method.");
NSLog(#"Creating a cell..");
//Create a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
//The above line used to reuse the memory in a tableView only allocate memory which is displayed at a time.
if(cell == nil){
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
NSLog(#"Filling Cell Content..");
//Fill it with Contents
cell.textLabel.text = [test objectAtIndex:indexPath.row];
NSLog(#"Cell content === %#",cell.textLabel.text);
NSLog(#"Exit cellForRowAtIndexPath method.");
//return it
return cell;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSArray *secTitle = [[NSArray alloc]initWithObjects:#"A",
#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",
#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",
#"T",#"U",#"V",#"W",#"X",#"Y",#"Z", nil];
return secTitle;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"In viewDidLoad method");
//Load from the plist File.
NSString *str = [[NSBundle mainBundle] pathForResource:#"groupedTest" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:str];
NSLog(#"dict === %#",dict);
test = [[NSArray alloc]initWithArray:[dict objectForKey:#"statesOfIndia"]];
//NSLog(#"In viewDidLoad method & Array fill from plist");
NSLog(#"Array count(Length) starts from 1 not 0 = %d",test.count);
NSLog(#"Exit from viewDidLoad method..");
// Do any additional setup after loading the view, typically from a nib.
}
In this test is my NSArray declared in .h file. And please tell me the answer because i start learning before 5 days only so i'm totally new in iPhone and objective C. Thank You Very Much!!
There is an option in UITableView for this use case, implement the UITableViewDataSource delegate methods
-sectionIndexTitlesForTableView: and
-tableView:sectionForSectionIndexTitle:atIndex:
For customising section titles and supporting localisation,
UILocalizedIndexedCollation need to be used. You can read about it here
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
- (NSInteger)tableView:(UITableView *)tableView
sectionForSectionIndexTitle:(NSString *)title
atIndex:(NSInteger)index
{
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
You will need to implement the below method to handle user touch on a section title
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [secTitle indexOfObject:title];
}

Set delegate to an object

This is the first time im trying to set a UITableView delegate/datasource to an instance of an object.
I have a UIView managed by a class called hMain, and a UITableView inside of main managed by an instance of a class called vTable.
hMain.h:
#interface hMain : UIViewController
#property (strong, nonatomic) IBOutlet vTable *voteTbl;
#end
hMain.m:
- (void)viewDidLoad
{
[super viewDidLoad];
voteTbl = [[vTable alloc]init];
[self.voteTbl setDelegate:voteTbl];
[self.voteTbl setDataSource:voteTbl];
}
vTable.h:
#interface vTable : UITableView <UITableViewDelegate , UITableViewDataSource>
#end
vTable.M:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [UITableViewCell configureFlatCellWithColor:[UIColor greenSeaColor] selectedColor:[UIColor wetAsphaltColor] reuseIdentifier:CellIdentifier inTableView:(UITableView *)tableView];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[cell configureFlatCellWithColor:[UIColor greenSeaColor] selectedColor:[UIColor wetAsphaltColor]];
}
cell.textLabel.text = #"Hello there!";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Row pressed!!");
}
This is really my first time straying away from IB and doing things programatically so im not sure im settings delegates and things correctly. This is also my first attempt and setting a delegate/datasource outside of self.
My problem is the table is coming out blank every time.
What is vTable? Looks like you have a "voteTable" class (BTW: classes should start with an uppercase char, instance variables should start with lowercase). Anyhow, looks like your main problem is you forgot to add the table as a subview and set its frame. eg:
self.voteTbl = [[VoteTable alloc] init];
self.voteTbl.delegate = self;
self.voteTbl.dataSource = self;
self.voteTbl.frame = self.view.bounds;
[self.view addSubView:self.voteTbl];

Resources