I am creating such table view which has not specified the number of sections (that means number of sections should be specified dynamically in its respected delegate i.e. - -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView) or not specified the rows in each sections (That means the number of rows in each sections also should be specified by dynamically in its respected delegates i.e.- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section) as below image in which the section of table specifies the month with year and each section can have any number of rows. The image is -
as above image january 2014 section has 4 rows and december 2013 has 2 rows. I would like to create such type of table view. Is it possible ? if it is possible than please provide proper way or any example or any link through which I can achieve it. Thanks in advanced.
Please Use below Code. Hope It will be useful to u.
in .h file defile
int i
in viewdidload method of .m file
arrData = [NSMutableArray array];
int temp = 1;
for (i = 0; i < 5; i++) {
NSMutableArray * arrIndexData = [NSMutableArray array];
for (int j = 0; j<=i; j++,temp++) {
[arrIndexData addObject:[NSString stringWithFormat:#"%d",temp]];
}
[arrData addObject:arrIndexData];
}
Now in numberOfSectionsInTableView
return i;
in numberOfRowsInSection
return [arrData count];
in cellForRowAtIndexPath
static NSString *CellIdentifier = #"Cell";
CustomCell * cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
[cell reloadTableWithArrData:[arrData objectAtIndex:indexPath.row]];
return cell;
I hope, this ll help u..
#Jekil , Just set Your DateFormatter to MMMM yyyy ,
Check my updated Answer
As all suggests use Array of Dictionary in Dictionary put two object one for Title (Nsstring) and second is NSArray ( dict for cell detail),
I have implemented One method for that in my app,
NOTE: Use Your Key Values for your data.
Use Following code for Arranging Array,
-(NSMutableArray*)arrangeSection:(NSMutableArray *)source
{
NSDateFormatter *_formatter=[[NSDateFormatter alloc]init];
[_formatter setLocale:[NSLocale currentLocale]];
[_formatter setDateFormat:#"MMMM yyyy"];
NSMutableArray *arrayMain=[NSMutableArray array];
for (int i=0; i<source.count; i++){
NSDictionary *dict=source[i];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[[dict objectForKey:#"StartDate"]doubleValue]];
NSString *mm=[_formatter stringFromDate:date];
NSMutableDictionary *secDict=[NSMutableDictionary dictionary];
NSMutableArray *secArray=[NSMutableArray array];
if (i==0){
[secDict setObject:mm forKey:#"Month"];
[secArray addObject:dict];
[secDict setObject:secArray forKey:#"Data"];
[arrayMain addObject:secDict];
}
else{
BOOL flg=NO;
for (NSDictionary *dict2 in arrayMain){
if([[dict2 objectForKey:#"Month"]isEqualToString:mm]){
flg=YES;
[[dict2 objectForKey:#"Data"]addObject:dict];
break;
}
}
if (!flg){
[secDict setObject:mm forKey:#"Month"];
[secArray addObject:dict];
[secDict setObject:secArray forKey:#"Data"];
[arrayMain addObject:secDict];
}
}
}
return arrayMain;
}
Now in tableview Methods use as,
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return arrayEvents.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[arrayEvents[section]objectForKey:#"Data"]count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...
NSDictionary *aDict = [arrayEvents objectAtIndex:indexPath.section];
NSDictionary *maindict=[[aDict objectForKey:#"Data"]objectAtIndex:indexPath.row];
...
}
Related
How to filter tableview based on a picker value?
I have the following NSMutableArray:
[0]:Object 1 (name1, October)
[1]:Object 2 (name2, November)
[2]:Object 3 (name3, March)
[3]:Object 4 (name4, April)
[4]:Object 5 (name5, April)
The table view displays the value of these objects.
and I have a picker with month values (January, February,... etc)
so based on the user selection of picker value, the table view should display values for example if I choose month April, only these values object 3 and 4 should appear.
Solution code, thanks to Fennelouski: (just thought I'd put it here In case someone needs it)
NSMutableArray *array;
NSMutableArray *filteredArray;
int monthInt;
NSString *monthString;
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Titles *object1 = [[Titles alloc]init];
[object1 setTitle:#"Title1"];
[object1 setMonth:#"10"];
Titles *object2 = [[Titles alloc]init];
object2.title = #"Title2";
object2.month = #"10";
Titles *object3 = [[Titles alloc]init];
object3.title = #"Title3";
object3.month = #"4";
array = [[NSMutableArray alloc]init];
filteredArray = [[NSMutableArray alloc]init];
[array addObject:object1];
[array addObject:object2];
[array addObject:object3];
pickerData = #[#"Jan", #"Feb", #"March", #"April", #"May", #"June", #"July", #"Aug", #"Sept", #"October", #"Nov", #"Dec"];
NSDate *currentDate = [NSDate date];
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:currentDate];
monthInt= [components month];
monthString = [NSString stringWithFormat:#"%li",(long)monthInt];
for (Titles *item in array)
{
if([item.month isEqualToString:monthString])
{
[filteredArray addObject:item];
}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [filteredArray count];
}
- (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];
}
Titles *titles = filteredArray[indexPath.row];
cell.textLabel.text = titles.title;
cell.imageView.image = [UIImage imageNamed:#"totoro.jpg"];
NSLog(#"Cell is %#", [array objectAtIndex:indexPath.row]);
return cell;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return pickerData.count;
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return pickerData[row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(#"Row: %li", (long)row);
monthString = [NSString stringWithFormat:#"%li",row+1];
[filteredArray removeAllObjects];
for (Titles *item in array)
{
if([item.month isEqualToString:monthString])
{
[filteredArray addObject:item];
}
}
[self.tableview reloadData];
}
It seems like you're following the design pattern of having your table view represent information stored in a separate data structure. That's good and makes filtering much easier.
Fortunately, you don't have to really do much with the table view to filter the results. All you need to do is filter the data structure that your table view is reading from and then update the table view.
I'd recommend adding an array in between your mutable array and the table view.
Something like this should work well for you
NSMutableArray *filteredObjects = [NSMutableArray new];
for (MYObjectClass *object in myMutableArray) {
if ([object.stringProperty isEqualToString:#"Filter"]) {
[filteredObjects addObject:object];
}
}
Then have your table view reference filteredObjects rather than the array you're using that has all of your data.
I have created a UITableView with custom cell & stored name,no,pincode in to these cell.
Here is my Code for array:-
for (int i =0; i<[tempArr count]; i++)
{
NSString *rawData = [tempArr objectAtIndex:i];
if (rawData !=nil)
{
Persons *newPerson = [[Persons alloc]init];
NSArray *data = [rawData componentsSeparatedByString:#"\t"];
newPerson.name = [NSString stringWithFormat:#"%#",[data objectAtIndex:0]];
newPerson.no = [[data objectAtIndex:1] integerValue];
newPerson.pincode = [[data objectAtIndex:2] integerValue];
[allPersons addObject:newPerson];
}
}
Here is my Customcell.h
#interface Customcell : UITableViewCell
#property(weak) Persons* person;
#end
UITableView Datasrouce method:-
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Customcell *cell = [tblStations dequeueReusableCellWithIdentifier:#"personCell"];
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.person = filteredContentList[indexPath.row];
[cell.textLabel setText:cell.person.name];
}
else
{
cell.person = allPersons[indexPath.row];
[cell.textLabel setText:cell.person.name];
}
return cell;
}
How do i create Section & index list for all names from A to Z & give title by cell.textLabel.text?
I am following This Tutorial but it has static keys & names added to NSDictionary,NSArray.
In my example i do not know how many names starting with same letter can come in the array. i am also using UISearchDisplayController for search person name.
I want to add number of sections & title for those sections by names that is in the array or cell.textLabel.text dynamically.
i do not know about UISearchDisplayController that these sections & index list will be displaying in UISearchDisplayController so i do not want these sections & index list while searching.
You need to spend a little more time trying to make your questions more clear.
Include a custom implementation of the necessary UITableView data source and delegate methods...
NOTE my assumption that your variable allPersons is an NSMutableArray.
NOTE these do not include for your search results data sets!
Return an NSInteger for the number of sections in your UITableView...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSSet *setData = nil;
NSInteger integerData = 0;
setData = [NSSet setWithArray:allPersons];
integerData = [setData count];
return integerData;
}
UPDATE
Return an NSString for section header titles...
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSOrderedSet *setData = nil;
NSString *stringData = nil;
setData = [NSOrderedSet orderedSetWithArray:allPersons];
stringData = [[setData allObjects] componentsJoinedByString:#" "];
return stringData;
}
...plus others if I have the time...
I want to filter an array with predicate and show it in tableView, every row of the array should be displayed in one section, but nothing is shown when I run my app.
When I try it with the unfiltered array it works. I don't know what to do because the two arrays have the same structure, the only difference is that the unfiltered array contains 17 objects and the filtered one 11.
Here's my code:
In viewDidLoad:
//itemsArray gets filled like this:
NSMutableArray *itemsArray = [[NSMutableArray alloc] init];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:abfahrt,#"Abfahrt",ankunft,#"Ankunft",nil];
[items addObject:dict];
//Date converted to string
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm"];
NSString *stringDate = [dateFormatter stringFromDate:gDate];
//filtered with stringDate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Abfahrt < %#", stringDate];
filteredArray = [itemsArray filteredArrayUsingPredicate:predicate];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return filteredArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ErgebnisCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *abfahrtLabel = (UILabel *)[cell viewWithTag:1];
UILabel *ankunftLabel = (UILabel *)[cell viewWithTag:2];
abfahrtLabel.text = [[filteredArray objectAtIndex:indexPath.section] objectForKey:#"Abfahrt"];
ankunftLabel.text = [[filteredArray objectAtIndex:indexPath.section] objectForKey:#"Ankunft"];
return cell;
}
Sounds like your filteredArray is empty, meaning your predicate is excluding everything from your list.
Put a breakpoint on the filteredArray line to see what's in there.
Alternately, put a breakpoint inside of numberOfSectionsInTableView, and see what filteredArray.count is. If it's zero, then tweak your predicate until some of your entries can make it through.
You may also find the methods listed under the "identifying and comparing strings" section of the NSStringClassReference to be helpful in forming the predicate you want. Especially any of the "compare" methods.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html
I have some JSON data that I am getting from my database. I can pull it fine and load it into my table view. my issue is separating my JSON data so I can section the tableview.
JSON
[{"id":"1","name":"steve mans","phoneNumber":"(559)123-4455","showNumber":"1","greenCard":"1","expiration":"2014-02-15","driver":"1","paid":"1","watch":"1"},
{"id":"2","name":"myself and me","phoneNumber":"(559)321-6784","showNumber":"1","greenCard":"1","expiration":"2013-10-18","driver":"0","paid":"0","watch":"2"},
{"id":"4","name":"tod bellesmithson","phoneNumber":"(559)678-3421","showNumber":"0","greenCard":"1","expiration":"2013-11-22","driver":"1","paid":"0","watch":"2"},
{"id":"3","name":"John Smith","phoneNumber":"(559)123-1234","showNumber":"1","greenCard":"0","expiration":"2013-10-08","driver":"0","paid":"1","watch":"3"},
{"id":"5","name":"greg smith","phoneNumber":"559 345-1234","showNumber":"1","greenCard":"1","expiration":"2013-10-08","driver":"0","paid":"1","watch":"3"}]
What I am trying to do is, separate this data into three sections in my tableview. So I thought create three different tables and load each table into a different section of the tableview. But the information is the same in each one (id, name, phone etc.) So I ended up with one table and added a column that designates what shift people work, 'watch'. So how do I separate the data by using the watch column, so in my tableview i will have:
section one
people who work night shift
section two
people who work morning
section three
night shift
Try with this code:
NSArray *data = (NSArray)[NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&error];
NSMutableArray *morningShift = [NSMutableArray array];
NSMutableArray *noonShift = [NSMutableArray array];
NSMutableArray *nightShift = [NSMutableArray array];
for (int i=0; i< [data count]; i++)
{
NSDictionary *item = data[i];
if (#"1" == item[#"watch"] )
{
[morningShift addObject:item];
} else if (#"2" == item[#"watch"] )
{
[noonShift addObject:item];
} else if (#"3" == item[#"watch"] )
{
[nightShift addObject:item];
}
}
try this
NSMutableArray *tableData = [NSMutableArray alloc] init];
NSArray* nameArr = [NSArray arrayWithObjects: #"1", #"2",#"3",nil];
for(int i=0; i<[nameArr count]; i++)
{
[tableData addObject:[jsonArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"watch = %#",[nameArr objectAtIndex:i]]] ];
}
TableView Delegate Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [tableData count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[tableData objectAtIndex:section ] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell= nil;
//implement your logic to display the cell item;
NSArray sectionData = [tableData objectAtIndex:indexPath.section];
NSArray rowData = [sectionData objectAtIndex:indexPath.row];
return cell;
}
Please note i have not compiled the code. There is a chance of compilation error.
check for section in your cellForRowAtIndexPath method and load data accordingly,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//initialize cell
if (indexPath.section == 0){
// load data
}
return cell;
}
Now I meet a strange situation, I need your help, and forgive my poor English.
When a UITableView, filled with NSArray, on the top, really reload data when I use [UITableView reloadData]. But, the table doesn't reload data if it's not on the top side. In fact, the app crashed. The strange thing is that the indexPath.section isn't the right value, bigger than real value. So the console said: index 2 beyond bounds [0..1].
Does anybody know why? Please give me a hand or a tips.
Below are some codes:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (pageCount == 0) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"IPOCalendarTableTitle" object:nil];
return 0;
} else {
NSMutableArray *arrayMonths = [stockArray objectAtIndex:pageIndex];
NSMutableArray *arrayDays = [arrayMonths objectAtIndex:0];
IPOListing *listing = [arrayDays objectAtIndex:0];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy/MM/dd";
NSDate *date = [formatter dateFromString:listing.date];
NSString *s = nil;
NSArray *arrayMonthEN = [NSArray arrayWithObjects:#"Jan", #"Feb", #"Mar", #"Apr", #"May", #"Jun", #"Jul", #"Aug", #"Sep", #"Oct", #"Nov", #"Dec", nil];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if ([delegate.currentLanguage isEqualToString:#"SC"]) {
formatter.dateFormat = #"yyyy年M月";
s = [formatter stringFromDate:date];
} else if ([delegate.currentLanguage isEqualToString:#"TC"]) {
formatter.dateFormat = #"yyyy年M月";
s = [formatter stringFromDate:date];
} else if ([delegate.currentLanguage isEqualToString:#"EN"]) {
int year = [[listing.date substringWithRange:NSMakeRange(0, 4)] intValue];
int month = [[listing.date substringWithRange:NSMakeRange(5, 2)] intValue];
s = [NSString stringWithFormat:#"%#, %d", [arrayMonthEN objectAtIndex:month - 1], year];
}
[formatter release];
NSArray *array = [NSArray arrayWithObjects:s, [NSNumber numberWithInt:pageCount], [NSNumber numberWithInt:pageIndex], nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"IPOCalendarTableTitle" object:array];
NSLog(#"%d", [arrayMonths count]);
return [arrayMonths count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSMutableArray *arrayMonths = [stockArray objectAtIndex:pageIndex];
NSMutableArray *arrayDays = [arrayMonths objectAtIndex:section];
return [arrayDays count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 36.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"IPOCalendarCellIdentifier";
IPOCalendarCell *cell = (IPOCalendarCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"IPOCalendarCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.lineLabel.backgroundColor = [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSLog(#"%d, %d", indexPath.section, indexPath.row);
NSMutableArray *arrayMonths = [self.stockArray objectAtIndex:pageIndex];
NSMutableArray *arrayDays = [arrayMonths objectAtIndex:indexPath.section];
IPOListing *listing = [arrayDays objectAtIndex:indexPath.row];
// configuration the cell...
return cell;
}
If indexPath.section isn't the right value, I'm pretty sure it has something to do with the value you return in - (NSInteger) numberOfRowsInSection:(UITableView *)tableView
Check this first, because If the size of your array is two, so as the value return by numberOfRowsInSection:, indexPath.section can't be equal or greater than this value.
Fixed. The problem is not here, it is about that two gang tables. When I use [UITableView setContentOffset] to table A, B will refresh too. In this case table A will reloadData twice, and when contentOffset of table is zero, it will reloadData only once. When table reloadData twice in quick time, it crashes. Thank all of you and I feel so sorry for my mistake.