Iphone NSArray and Sections - iphone

I am currently developing an app to show fixtures in a football competition using data held in NSArrays. I would like to now put the data into section i.e. for example Round 1 showing 3 matches, Round 2 Showing 6 matches etc.
Can someone please assist me with how I can show the data in a UITable in sections?
Regards
John

I usually use NSArrays in a NSArray for this.
This is how I would create the datasource array:
NSArray *section0 = [NSArray arrayWithObjects:#"Section 0 Row 0", #"Section 0 Row 1", nil];
NSArray *section1 = [NSArray arrayWithObjects:#"Section 1 Row 0", #"Section 1 Row 1", #"Section 1 Row 2", nil];
self.tableViewData = [NSArray arrayWithObjects:section0, section1, nil];
and some UITableView methods so you get the idea:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.tableViewData count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.tableViewData objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyObject *object = [[self.tableViewData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
// Do something
}
And for the titles (and indexes) of the sections I create separate NSArrays.

better to create Array of Array . suppose you have 3 sections and every section have 4 rows . so create one array with three array object .and each inner array will contains the rows value

You need to create a class that conforms to the UITableViewDataSource protocol. This class is typically a subclass of UIViewController. You should then set the dataSource property of a UITableView to point to an instance of this class. Your data source class should implement the method sin the protocol so as it returns values based in the data in your model (hence this is a controller class). If it helps, you can also use the UIViewController subclass UITableViewController.

Related

How to keep track of selected indexes (in array) in a UITableViewController Which contains another UITableView as its Cells

with the help of THIS Tutorial . . . .
I made a UITableViewController (for reference I can call it MainTableVC)
, which has single row in each of its section
and
I made every cell of this UITableViewController(MainTableVC) a UITableView (for reference I can call it UITableViewOfMainTableVCell) with many cells.
Now I rotated Cell/rows of UITableViewOfMainTableVCell {* its a UITableView not a UITableViewCell },
so that i could scroll cells of UITableViewOfMainTableVCell horizontally.
now my UI looks like this,
I have a table with 10 section(say), each section has one row/cell and in this row/cell i have several rows/cells which can be scrolled horizontally
I also enabled allowMultipleSelections in custom cells of UITableViewOfMainTableVCell
Now I wanted to keep track of selected indexes of selected rows
so
I took an NSArray and saved indexPaths in it with this delegate method of UITableViewOfManiTableVCcells
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *selectedIndexesOfOneRow = [NSMutableArray arrayWithArray:[tableView indexPathsForSelectedRows]];
NSLog(#"number of selected Indexes = %d",[selectedIndexesOfOneRow count]);
}
-(void)tableView:(UITableView *)tableView didDeSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *selectedIndexesOfOneRow= [NSMutableArray arrayWithArray:[tableView indexPathsForSelectedRows]];
NSLog(#"number of selected Indexes = %d",[selectedIndexesOfOneRow count]);
}
MY PROBLEM :-
suppose if I select 4 cells/rows in a row/cell of MainTableVC
the NSMutableArray *selectedIndexesOfOneRow has the right count
BUT
if I select cells of another a row in another section of MainTableVC with even keeping previous cells selected
the count starts from beginning
the problem is with indexPathsForSelectedRows,
it only keeps track of Selected Rows of single UITableView,
since i have separate UITableViews for each Row of Each Section of MainTableVC
NSMutableArray always gets reset when select cells from different row
MY QUESTION
since every Row/Cell calls the same UITableView delegate method,
how will I prevent it,
I want to store all the selected indexes of cells in whole UI
I could make an array of array to store indexes of different different indexes
but how would i get those differently
"HINT"
I could do somthing like this,
in my MainTableVC,
Since i have a tableView inside Cell of MainTableVC i can put an NSArray *array = [cell.tableView indexPathsOfSelectedIndex], but again in which delegate method of MainTableVC should i put this, and also i have checked, Since i am not selecting any whole row of MainTableVC(UITableViewController), its delegate methods didSelectRowAtIndexPath and didDeSelectRowAtIndexPath never get called
You can assing tag to your tableView, then check tag to distinguish all tableView.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag==1) {
//Do what ever you want with table having tab =1
}else if (tableView.tag==2) {
//Do what ever you want with table having tag =2
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// NSLog(#"user selected %#",[dataArray objectAtIndex:indexPath.row]);
NSString *listOfFacebookIDs = #"";
NSArray *indexPathArray = [self.mTableView indexPathsForSelectedRows];
for(NSIndexPath *index in indexPathArray){
//Assuming that 'idFriends' is an array you've made containing the id's (and in the same order as your tableview)
//Otherwise embed the ID as a property of a custom tableViewCell and access directly from the cell
//Also assuming you only have one section inside your tableview
NSString *fbID = [dataArray objectAtIndex:index.row];
if([indexPathArray lastObject]!=index){
listOfFacebookIDs = [listOfFacebookIDs stringByAppendingString:[fbID stringByAppendingString:#", "]];
}else{
listOfFacebookIDs = [listOfFacebookIDs stringByAppendingString:fbID];
}
}
NSLog(#"Your comma separated string is %#",listOfFacebookIDs);
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"user de-selected %#",[dataArray objectAtIndex:indexPath.row]);
}

UITableView in Storyboard appears empty

It's my first time using Storyboard to build an app. I'm trying to create a UITableView with a custom cell. I've created the cell in IB and created a custom tableViewCell class for it (added some labels, created appropriate outlets, connected them in IB and assigned the custom class to the custom cell in IB).
In the ViewController responsible for the TableView I create the data source (a dict with some arrays) and fill out all the obligatory methods (I've tried both with UITableViewControler and with a UIViewController that is set as a delegate and data source for the tableview)
And when I run the app - the tableview is empty. And after doing some NSLogging I've noticed that the data source methods are never executed. And I have NO IDEA why.
I'm going crazy about this for a few hours now. Please help me out :)
Let me know if you need to see the code or Storyboard, or whatever else.
UPDATE: Alright, after some digging, I've decided to test out the same code but using an NSMutableArray as data source instead of a NSMutableDictionary. And it works!
Now, could someone explain to me why it didn't work with a dict?
Here's what did. I had a dict with 5 arrays, and each array had 5 strings.
In the numberOfRowsForSection method, I returned [dict count]
And in the cellForRowAtIndexPath method, I've used this code
NSArray * routeArray = [dealsDict objectForKey:#"route"];
cell.routeName.text = [routeArray objectAtIndex:indexPath.row];
NSArray * companyArray = [dealsDict objectForKey:#"company"];
cell.companyName.text = [companyArray objectAtIndex:indexPath.row];
NSArray * priceArray = [dealsDict objectForKey:#"price"];
cell.priceLabel.text = [priceArray objectAtIndex:indexPath.row];
NSArray * dateArray = [dealsDict objectForKey:#"date"];
cell.dateLabel.text = [dateArray objectAtIndex:indexPath.row];
NSArray * monthArray = [dealsDict objectForKey:#"month"];
cell.monthLabel.text = [monthArray objectAtIndex:indexPath.row];
NSLog(#"I'm in here");
return cell;
why didn't it want to show anything?
In the IB, select your table view, and make sure that the delegate and dataSource outlets are set for your controller
UITableView need some collection dataset as data source. Its delegate method "cellForRowAtIndexPath" get called equals to number of elements of collection (ARRAY). like numberOfRowsInSection delegate tells the table view that it need to call cellForRowAtIndexPath for every element in collection. and it also need some iterator to read each time the next element, in case of dictionary it always stick to same data element at each call of cellForRowAtIndexPath. I hope it wil give you the idea of its working, Please let me know if you need anything else to know.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MessagesCell *cell = [tableView dequeueReusableCellWithIdentifier:#"messageCellIdentifier"];
Message *msg = [self.data objectAtIndex:indexPath.row];
cell.Name.text = msg.Name;
cell.Message.text = msg.MessageText;
cell.Time.text = msg.Time;
return cell;
}

How to get a UITableViewCell's subtitle show how many times that specific cell was tapped?

I have a uitableview that displays the values of an array. I would like to know if there is a way to update the subtitle of its table cells, based on how many times each cell was tapped.
Thank you!
First of all, you'll want to use a NSMutableArray so you can change its contents after instantiation. Here's a basic over view of what I just tried to achieve your intended results:
In your interface
#property (strong, nonatomic) NSMutableArray *tapCountArray;
In your implementation
- (void)viewDidLoad
{
[super viewDidLoad];
self.tapCountArray = [NSMutableArray new];
int numberOfRows = 20;
for (int i = 0; i < numberOfRows; i ++) {
[self.tapCountArray addObject:#(0)];
}
}
Then the important part!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tapCountArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *text = [self.tapCountArray[indexPath.row] stringValue];
[cell.textLabel setText:text];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tapCountArray replaceObjectAtIndex:indexPath.row withObject:#([self.tapCountArray[indexPath.row] intValue] + 1)];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
When each cell is tapped the number in its detailTextLabel will be incremented up by one.
You shouldn't create a new array or set, that could lead to problems if the two arrays get out of sync with each other. The way to do it, as you suggested in your comment, is to use dictionaries. The way you said you were doing that is probably not the way, however. You want an array of dictionaries where the values for one key would be whatever your main data is and the value for the other key would be the number of taps. For example, lets call the two keys main and sub, and your main data is a set of names. The array of dictionaries would look like this: ({main:#"Tom",sub:1}, {main:#"Dick", sub:0}, {main:#"Harry",sub:2}, .....). In the tableView:cellForRowAtIndexPath:indexPath method you would provide the data to the cells like this:
cell.textLabel.text = [[array objectAtIndex:indexPath.row] valueForKey:#"main"];
cell.detailTextLabel.text = [[array objectAtIndex:indexPath.row] valueForKey:#"sub"];
I think you can just set up another array of the same length as the one you have now. Then when your didSelectRowAtIndexPath is triggered, increment your indexPath.row entry of the new array and refresh that cell. If you don't expect to shuffle the table, you don't need a dictionary.
You can insert the object into an NSCountedSet, and on your cellForRowAtIndexPath method, you would take the model object for the cell and verify the number of times it has been inserted into the NSCountedSet instance.
Take a look at the NSCountedSet documentation: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSCountedSet_Class/Reference/Reference.html

How to create a section table view which depends on the table view data in iPhone?

I want to create a sectioned table view. Using XML parsing, i got the datas and displayed in the table view. Now i want to check, whether the data is empty, then it shouldn't create the table view section. so i want to check it before create the table view. Which means, if the data is not empty then should create a section, otherwise can't create a section. SO the table view section only depends on the data(Empty or Not).
Here my sample code,
person = [[Person alloc] initWithPersonName:DictionaryValue]; // Passing the values via Dictionary.
[self.navigationController pushViewController:person animated:YES];
In Person Class:
-(Person *) initWithPersonName:(NSMutableDictionary *) personDict
{
self.tableView.delegate = self;
[[NSBundle mainBundle] loadNibNamed:#"Person" owner:self options:nil];
NSString *firstName = [personDict valueForKey:#"firstName"];
NSString *lastName = [personDict valueForKey:#"lastName"];
NSString *cityName = [personDict valueForKey:#"city"];
NSString *stateName = [personDict valueForKey:#"state"];
return self;
}
I want to create the two sections,
section - 1 -- > [firstName, LastName];
section - 2 -- > [city, state];
How can i put those section values into the arrays. Is possible to create a single array to use both sections or Need to create a separate array for store the separate sections.
Suppose i get the empty value for any data, so it shouldn't create a table view section. What are the possibilities to achieve this? Please guide me.
Please give me any sample code or sample link.
Thanks.
You need to implement -numberOfSectionsInTableView:, -tableView:titleForHeaderInSection:, and -tableView:numberOfRowsInSection: in your UITableViewController subclass (create one if you don't already have one). The names are pretty self-explanatory. So you could do something like:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) return #"Title of section 1";
if (section == 1) return #"Title of section 2";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// return the number of rows you've got based on the section index
}
That, I believe, will create the section headers regardless of whether you've got rows in them or not, but nothing will show beneath it. So it will be clear that a section is empty if it has no data. Make sense?
Cody

date wise sorted uitableview

I am developing an iPhone application .
In the application I want to show the uitableview data sorted on the date field :
Suppose I have a Person object with fields name,birthdate,phone number etc.
Now I have array of Person and I am sorting that array on date field.
Now I am not understanding that how to handle these two methods ;
(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
i.e
How to count date wise objects and determine ?
Assuming you have one section and a sorted NSArray or NSMutableArray called _personArray:
- (NSInteger) numberOfSectionsInTableView:(UITableView *)_tableView {
return 1;
}
- (NSInteger) tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)_section {
return [_personArray count];
}
- (UITableViewCell *) tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)_indexPath {
Person *_person = [_personArray objectAtIndex:_indexPath.row];
NSString *_cellIdentifier = [NSString stringWithFormat: #"%d:%d", _indexPath.section, _indexPath.row];
UITableViewCell *_cell = [_tableView dequeueReusableCellWithIdentifier:_cellIdentifier];
if (_cell == nil) {
_cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:_cellIdentifier] autorelease];
}
_cell.textLabel.text = _person.name;
_cell.detailTextLabel.text = _person.birthdate;
return _cell;
}
If you require multiple sections, split your array into multiple NSMutableArray instances, each containing Person instances associated with a specific section.
Then modify -numberOfSectionsInTableView: to return the number of sections (a count of the number of section arrays), as well as the other two methods to: 1) get element counts within a section array and; 2) to recall the right Person for a given indexPath.section and indexPath.row.