Horizontally and Vertically scrollable table view with data from json - ios

I want to create a table view which is scrollable both horizontally and vertically. I can do this by taking values myself. But I want to take the values from json. I am using model class and my json values are like this:
[
{
"cid": 109,
"iid": 10653,
"yr": 1994,
"val": "15.4311527806175"
},
{
"cid": 109,
"iid": 7872,
"yr": 1999,
"val": "8.84575553637328"
},
{
"cid": 109,
"iid": 7872,
"yr": 1998,
"val": "6.18441582677751"
},
I want my first column to be fixed when scrolling horizontally and first row to be fixed when I scroll it vertically. First column should have iid. first row should have yr and data should have val.
I am using XCMltisortTableView, ASIHttpRequest and SBJson.
I am getting the header value and left column value. How can I get the data corresponding to the yr and iid in proper column?
My code for val in requestFinished method is as follows:
rightTableData = [NSMutableArray arrayWithCapacity:mainTableData.count];
NSMutableArray *right = [NSMutableArray arrayWithCapacity:mainTableData.count];
for (int i = 0; i < mainTableData.count; i++)
{
// Model *model = [mainTableData objectAtIndex:i];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:mainTableData.count];
for (int j = 0; j < headData.count; j++)
{
Model *model = [mainTableData objectAtIndex:j];
if([headData isEqual: #"2000"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2001"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2002"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2003"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2004"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
}
[right addObject:array];
}
[rightTableData addObject:right];
I'm totally new and would a appreciate any answers and any suggestions. Please do reply.
Thanks!

After trying for a long time I got the result using the code below:
-(void) requestFinished: (ASIHTTPRequest *) request
{
NSString *theJSON = [request responseString];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSMutableArray *jsonDictionary = [parser objectWithString:theJSON error:nil];
headData = [[NSMutableArray alloc] init];
NSMutableArray *head = [[NSMutableArray alloc] init];
leftTableData = [[NSMutableArray alloc] init];
NSMutableArray *left = [[NSMutableArray alloc] init];
rightTableData = [[NSMutableArray alloc]init];
for (NSMutableArray *dictionary in jsonDictionary)
{
Model *model = [[Model alloc]init];
model.cid = [[dictionary valueForKey:#"cid"]intValue];
model.iid = [[dictionary valueForKey:#"iid"]intValue];
model.yr = [[dictionary valueForKey:#"yr"]intValue];
model.val = [dictionary valueForKey:#"val"];
[mainTableData addObject:model];
[head addObject:[NSString stringWithFormat:#"%ld", model.yr]];
[left addObject:[NSString stringWithFormat:#"%ld", model.iid]];
}
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:head];
headData = [[orderedSet array] mutableCopy];
NSOrderedSet *orderedSet1 = [NSOrderedSet orderedSetWithArray:left];
NSMutableArray *arrLeft = [[orderedSet1 array] mutableCopy];
//remove duplicate enteries from header array
[leftTableData addObject:arrLeft];
NSMutableArray *right = [[NSMutableArray alloc]init];
for (int i = 0; i < arrLeft.count; i++)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int j = 0; j < headData.count; j++)
{
/* NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.iid == %ld", [[arrLeft objectAtIndex:i] intValue]];
NSArray *filteredArray = [mainTableData filteredArrayUsingPredicate:predicate];*/
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.iid == %ld AND SELF.yr == %ld", [[arrLeft objectAtIndex:i] intValue], [[headData objectAtIndex:j] intValue]];
NSArray *filteredArray = [mainTableData filteredArrayUsingPredicate:predicate];
if([filteredArray count]>0)
{
Model *model = [filteredArray objectAtIndex:0];
[array addObject:model.val];
}
}
[right addObject:array];
}
[rightTableData addObject:right];
}
Hope it helps others.

Related

How to check array is empty in iPhone

I have one array of array.I want check my inner array is empty or not.and I am checking objects of array are empty string.
Here is my code :
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (int i = 0; i < [newArray count]; i++)
{
NSArray *arr = [newArray objectAtIndex:i];
if ([arr count] > 0)
{
NSString *str = [arr objectAtIndex:0];
if (![str isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}
my newArray is array of array.I want to add strings in selectArray which are not empty.but, only 0th index object is added in selectArray multiple times.
Please suggest me, where i am doing wrong.thanks
Thats because you are just getting the 0'th element of your newArray's elements, I mean this line
NSString *str = [arr objectAtIndex:0];
you should put another for in your code. Use this code instead of yours
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (int i = 0; i < [newArray count]; i++){
NSArray *arr = [newArray objectAtIndex:i];
for (int j = 0; j < [arr count]; j++){
NSString *str = [arr objectAtIndex:j];
if (![str isEqualToString:#""]){
[selectArray addObject:str];
}
}
}
Use this code You not need to create any extra variable.
for (int i = 0; i < [newArray count]; i++)
{
for (int j = 0; j < [[newArray objectAtIndex:i] count]; j++)
{
if (![[[newArray objectAtIndex:i] objectAtIndex:j] isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}
You can use following generic function to check any of the value or object is empty or null.
-(BOOL)isEmpty:(id)object{
return object == nil
|| [object isKindOfClass:[NSNull class]]
|| ([object respondsToSelector:#selector(length)]
&& [(NSData *)object length] == 0)
|| ([object respondsToSelector:#selector(count)]
&& [(NSArray *)object count] == 0);
}
You can try with this
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (NSArray *arrayFromNewArray in newArray) {
if ([arrayFromNewArray count] > 0)
{
NSString *str = [arrayFromNewArray firstObject];
if (![str isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}
You should be
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (int i = 0; i < [newArray count]; i++)
{
NSArray *arr = [newArray objectAtIndex:i];
for (int j = 0; j < [arr count]; j++)
{
NSString *str = [arr objectAtIndex:j];
if (![str isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}
Problem is you forgot the second loop :) Let me know if I am correct.

displaying emailaddress corresponding to name from address book in ios

I have an application in which I have a UITextField where when I enter a character in UITextField it searches for any matches in my address book and if any match is found it display name and emailaddress of the respective person on a UITableView.
My problem is I am not able to search properly using predicate on my address book. When I enter any character it always displays the last record whether it matches my predicate or not.
This is my code. This is my textfieldchange method:
-(void)textFieldDidChange:(UITextField *)txtFld {
[self fetchAddressBook];
NSString *dictionaryKey = contact.name;
NSString *predicateString = contact.email;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[cd] %#", dictionaryKey, predicateString];
listFiles = [NSMutableArray arrayWithArray:[self.namearray
filteredArrayUsingPredicate:predicate]];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:contact.name ascending:YES] ;
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [listFiles sortedArrayUsingDescriptors:sortDescriptors];
if ([sortedArray count]>0)
{
tblView.hidden=FALSE;
txtSendAmount.hidden=TRUE;
txtSendMessage.hidden=TRUE;
[tblView reloadData];
}
else if ([sortedArray count]==0)
{
tblView.hidden=TRUE;
txtSendAmount.hidden=FALSE;
txtSendMessage.hidden=FALSE;
}
}
this is the code where i am fetching my email and name of person from address book and saving in an array
-(void)fetchAddressBook
{
CFErrorRef error = nil;
ABAddressBookRef allPeople = ABAddressBookCreateWithOptions(NULL,&error);
CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople(allPeople);
CFIndex numberOfContacts = ABAddressBookGetPersonCount(allPeople);
NSMutableArray *testarray = [[NSMutableArray alloc] init];
NSMutableDictionary *addressdict = [[NSMutableDictionary alloc] init];
for(int i = 0; i < numberOfContacts; i++){
name = #"";
NSString* phone = #"";
email = #"";
contact = [[MContact alloc] init];
ABRecordRef aPerson = CFArrayGetValueAtIndex(allContacts, i);
ABMultiValueRef fnameProperty = ABRecordCopyValue(aPerson, kABPersonFirstNameProperty);
ABMultiValueRef lnameProperty = ABRecordCopyValue(aPerson, kABPersonLastNameProperty);
ABMultiValueRef phoneProperty = ABRecordCopyValue(aPerson, kABPersonPhoneProperty);
ABMultiValueRef emailProperty = ABRecordCopyValue(aPerson, kABPersonEmailProperty);
NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
if (fnameProperty != nil) {
contact.name = [NSString stringWithFormat:#"%#", fnameProperty];
}
if (lnameProperty != nil) {
contact.name = [contact.name stringByAppendingString:[NSString stringWithFormat:#" %#", lnameProperty]];
}
if ([phoneArray count] > 0) {
if ([phoneArray count] > 1) {
for (int i = 0; i < [phoneArray count]; i++) {
phone = [phone stringByAppendingString:[NSString stringWithFormat:#"%#\n", [phoneArray objectAtIndex:i]]];
}
}else {
phone = [NSString stringWithFormat:#"%#", [phoneArray objectAtIndex:0]];
}
}
if ([emailArray count] > 0) {
if ([emailArray count] > 1) {
for (int i = 0; i < [emailArray count]; i++) {
contact.email = [contact.email stringByAppendingString:[NSString stringWithFormat:#"%#\n", [emailArray objectAtIndex:i]]];
}
}else {
contact.email = [NSString stringWithFormat:#"%#", [emailArray objectAtIndex:0]];
}
}
[self.emailnamearray addObject:contact];
self.namearray = [emailnamearray copy];
}
}
this is my cellforrowAtIndexPath method
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tblView dequeueReusableCellWithIdentifier:#"eventCell"];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"eventCell"];
}
MContact *addressdict = [listFiles objectAtIndex:indexPath.row];
cell.textLabel.text=addressdict.name;
cell.detailTextLabel.text=addressdict.email;
return cell;
}
Your bug is there:
NSString *dictionaryKey = contact.name;
NSString *predicateString = contact.email;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[cd] %#", dictionaryKey, predicateString];
The key should be #"name" or #"email", not a particular contact's name. Same for the sort descriptor.

How can I sort a second array based on a first array which was sorted with NSPredicate?

I have two NSMutableArrays: searchResults and searchResultsDetails. I sort searchResults with NSPredicate, and I want searchResultsDetails to be sorted based on which objects were removed from searchResults with the NSPredicate.
For example, let's say searchResults originally contains 1,2,3,4,5 and searchResultsDetails originally contains A,B,C,D,E. So after sorting it with NSPredicate, searchResults contains 1,2,5, and I want searchResultsDetails to contain A,B,E. How can I accomplish this?
This is the code I am using to sort the first array.
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"self CONTAINS %#",
searchText];
self.searchResults = [self.lines filteredArrayUsingPredicate:resultPredicate];
NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects:#"ashu",#"toremove",#"ashuabc",#"toremove",#"ashu12345", nil];
NSMutableArray *descriptionArray = [[NSMutableArray alloc] initWithObjects:#"description for ashu",#"description for non ashu",#"description for ashuabc",#"description for nopnashu",#"description for ashu12345", nil];
NSMutableArray *removedIndexArray = [[NSMutableArray alloc] init];
NSMutableArray *sortedArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [firstArray count]; i++) {
NSString *tempStr = [firstArray objectAtIndex:i];
if ([tempStr rangeOfString:#"ashu"].location == NSNotFound) {
[removedIndexArray addObject:[NSString stringWithFormat:#"%d",i]];
} else {
[sortedArray addObject:tempStr];
}
}
for (int j = 0; j < [removedIndexArray count]; j++) {
[descriptionArray removeObjectAtIndex:[[removedIndexArray objectAtIndex:j] integerValue]];
}
NSLog(#"%#",descriptionArray);
NSLog(#"Sorted array is :: %#",sortedArray);

Exception "mutating method sent to immutable object"

I Had an exception in the line [array removeObjectsInArray:toRemove]; in the method below and can't understand what's wrong with it..
- (void) handleDearchForTerm:(NSString *)searchTerm
{
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];
for (NSString *key in _keys)
{
NSMutableArray *array = [_names valueForKey:key];
NSMutableArray *toRemove = [[NSMutableArray alloc] init];
for (NSString *name in array)
{
if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound)
[toRemove addObject:name];
}
if ([array count] == [toRemove count])
[sectionsToRemove addObject:key];
[array removeObjectsInArray:toRemove];
}
[_keys removeObjectsInArray:sectionsToRemove];
[_table reloadData];
}
Probably array is just instance of NSArray, but not NSMutableArray, you shall check _names setObject:forKeys:
Change:
NSMutableArray *array = [_names valueForKey:key];
To:
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[_names valueForKey:key]];
Or:
NSMutableArray *array = [[_names valueForKey:key] mutableCopy];

how to change order of NSMutable array in same way another mutable arrays get changed

I have three arrays. They are name, birthdates and remaining days like below:
name birthdate remaining
"Abhi Shah", "01/14", 300
"Akash Parikh", "12/09/1989", 264
"Anand Kapadiya", "12/01", 256
"Annabella Faith Perez", "03/02", 347
"Aysu Can", "04/14/1992", 25
"Chirag Pandya" "10/07/1987" 201
I want to rearrange the remaining days array into ascending order,
but at the same time name and birthdate should also get reordered in the same way.
See this example below:
name birthdate remaining
"Aysu Can", "04/14/1992", 25
"Chirag Pandya" "10/07/1987" 201
"etc..."
use NSMutableDictionary to store data to NSMutableArray
NSMutableArray *array=[[NSMutableArray alloc]init];
for (int i=0; i<totalRows; i++)
{
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
[dic setValue:[array_1 objectAtIndex:i] forKey:#"names"];
[dic setValue:[array_2 objectAtIndex:i] forKey:#"birthdate "];
[dic setValue:[array_3 objectAtIndex:i] forKey:#"remanning"];
[array addObject:dic];
[dic release];
}
here after you arrange name array,use search option to use name not use index and
use NSPredicate search data in NSMutableArray
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"names matches[cd] %#", name];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSMutableDictionary *dict = [[[result objectAtIndex:0] mutableCopy] autorelease];
NSLog(#"%#",dict);// result
self.arrayForRows = [[NSMutableArray alloc]init];
NSMutableArray *arrayForNames = [[NSMutableArray alloc]initWithObjects:#"Abhi Shah",#"Akash",#"Nagavendra",#"Ramana",#"Simhachalam", nil];
NSMutableArray *arrayForBirthDates = [[NSMutableArray alloc]initWithObjects:#"01/14/94",#"01/14",#"11/07/87",#"12/07/89",#"23/08/91", nil];
NSMutableArray *arrayForRemaining = [[NSMutableArray alloc]initWithObjects:#"200",#"320",#"32",#"450",#"14", nil];
for (int i=0; i<arrayForBirthDates.count; i++)
{
NSMutableDictionary *tempDicts = [[NSMutableDictionary alloc]init];
[tempDicts setObject:[arrayForNames objectAtIndex:i] forKey:#"names"];
[tempDicts setObject:[arrayForBirthDates objectAtIndex:i] forKey:#"birth"];
[tempDicts setObject:[NSNumber numberWithInt:[[arrayForRemaining objectAtIndex:i] intValue]] forKey:#"remaining"];
[self.arrayForRows addObject:tempDicts];
}
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"remaining" ascending:YES];
[self.arrayForRows sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
Use this in tableView listing
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.arrayForRows count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifer = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
}
cell.textLabel.text = [[self.arrayForRows objectAtIndex:indexPath.row] valueForKey:#"names"];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
once try like this it'l help you,
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[dict setObject:#"rahul" forKey:#"name"];
[dict setObject:#"10" forKey:#"value"];
NSMutableDictionary *dict1=[[NSMutableDictionary alloc]init];
[dict1 setObject:#"ttt" forKey:#"name"];
[dict1 setObject:#"6" forKey:#"value"];
NSMutableArray *ar=[[NSMutableArray alloc]init];
[ar addObject:dict];
[ar addObject:dict1];
NSSortDescriptor *Sorter = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
[ar sortUsingDescriptors:[NSArray arrayWithObject:Sorter]];
NSLog(#"---%#",ar);
Put each row into a dictionary, and out those dictionaries into an array. Then sort your away using a predicate or sort block. If you want an array containing just the sorted names for example, you could use [ array valueForKeyPath:#"name" ]
Array looks like:
[
{ #"name" : ...,
#"birthdate" : ...birthdate...,
#"remaining" : ...days remaining... } ,
{...},
{...}
]
such as your MutableArray is a Dictionarys array , you can use sortUsingComparator
to sort the array
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
int a = [(NSNumber *)[(NSDictionary *)obj1 objectiveForKey: #"remanning"] intValue];
int b = [(NSNumber *)[(NSDictionary *)obj2 objectiveForKey: #"remanning"] intValue];
if (a < b) {
return NSOrderedAscending;
}
else if(a == b)
{
return NSOrderedSame;
}
return NSOrderedDescending;
}];
For example , I have a test :
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#(30),#(20),#(5),#(100), nil];
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
int a = [(NSNumber *)obj1 intValue];
int b = [(NSNumber *)obj2 intValue];
if (a < b) {
return NSOrderedAscending;
}
else if(a == b)
{
return NSOrderedSame;
}
return NSOrderedDescending;
}];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"%# , %d",obj,idx);
}];
then the output is :

Resources