I have a function to initialize an array of backpack objects, and a property of the backpack object is positive, negative, and neutral attributes, which are all NSStrings. The problem is that when I initialize the values of the attributes, the same value repeats twice (when I log the value of it)
The code:
#pragma mark - Creating Backpack Icons
-(NSArray *)createBackpackIcons:(NSArray *)groups usingItemGroups:(NSArray *)items
{
NSMutableArray *backpackItems = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < _groups.count; i++) {
Group *group = _groups[i];
NSString *defindex1 = [NSString stringWithFormat:#"%#", group.defindex];
for (NSInteger j = 0; j < _itemGroups.count; j++)
{
Item *item = _itemGroups[j];
NSString *defindex2 = [NSString stringWithFormat:#"%#", item.defindex];
if([defindex1 isEqualToString:defindex2])
{
//NSLog(#"%#", item.item_name);
backpackIcons *backpack = [[backpackIcons alloc] init];
backpack.pos_att = #"";
backpack.neg_att = #"";
backpack.neutral_att = #"";
//name of item
if([item.proper_name boolValue])
{
backpack.name = #"The ";
backpack.name = [backpack.name stringByAppendingString:item.item_name];
}
else
{
backpack.name = item.item_name;
}
backpack.original_id = group.original_id; //id of the item
backpack.defindex = item.defindex; //defindex number of the item
backpack.level = group.level; //level of the item
backpack.quality = group.quality; //quality of the item
backpack.image_url = item.image_url; //image of the item
backpack.item_description = item.item_description; //description of the item
backpack.image_url_large = item.image_url_large; //large image of the item
backpack.item_type = item.item_type_name; //type of item
//find origin of item
if(group.origin != NULL) {
backpack.origin = [item.originNames objectAtIndex:[group.origin integerValue]];
}
else {
backpack.origin = #"";
}
if([group.flag_cannot_craft boolValue])
{
//item isn't craftable
backpack.not_craftable = #"(Not Craftable)";
}
if([group.flag_cannot_trade boolValue])
{
//item isn't tradable
backpack.not_tradable = #"(Not Tradable)";
}
//custom name
if(group.custom_name != NULL) {
backpack.custom_name = group.custom_name;
}
//custom description
if(group.custom_desc != NULL) {
backpack.custom_desc = group.custom_desc;
}
//find positive and negative attributes of the item
if(group.attributes.count != 0) {
for(NSInteger num = 0; num < group.attributes.count; num++) {
NSString *att_def = [NSString stringWithFormat:#"%#",[[group.attributes objectAtIndex:num] valueForKey:#"defindex"]];
//NSLog(att_def);
for(NSInteger num2 = 0; num2 < item.attributes.count; num2++) {
NSString *att_def2 = [NSString stringWithFormat:#"%#", [[item.attributes objectAtIndex:num2] valueForKey:#"defindex"]];
//defindex of 214 is for counting kills on strange weapons
if(att_def2 != NULL) {
if ([att_def isEqualToString:att_def2]) {
//we have found the attribute!
if(![[[item.attributes objectAtIndex:num2] valueForKey:#"hidden"] boolValue]) {
//item isn't hidden from view
if(![[[item.attributes objectAtIndex:num2] valueForKey:#"stored_as_integer"] boolValue]) {
//we use the float value
if([[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"float_value"]] isEqualToString:#"1"] || [[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"float_value"]] isEqualToString:#"0"]) {
//the attribute is string only, it has no values
NSString *att_type = [[item.attributes objectAtIndex:num2] valueForKey:#"effect_type"];
NSString *attribute = [[item.attributes objectAtIndex:num2] valueForKey:#"description_string"];
if([att_type isEqualToString:#"positive"]) {
backpack.pos_att = [backpack.pos_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else if ([att_type isEqualToString:#"negative"]) {
backpack.neg_att = [backpack.neg_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else {
backpack.neutral_att = [backpack.neutral_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
}
}
else {
//the attribute uses values given my the float_value key
NSString *att_type = [[item.attributes objectAtIndex:num2] valueForKey:#"effect_type"];
double y = [[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"float_value"]] doubleValue];
NSInteger z;
if([[[item.attributes objectAtIndex:num2] valueForKey:#"description_string"] rangeOfString:#"%s1%"].location != NSNotFound) {
//for values with percentages
z = lroundf(y*100);
if(z >= 100) {
z = z - 100;
}
}
else {
//for values that are just integers
z = y;
}
NSString *a = [NSString stringWithFormat:#"%d", z];
NSString *attribute = [[[item.attributes objectAtIndex:num2] valueForKey:#"description_string"] stringByReplacingOccurrencesOfString:#"%s1" withString:a];
//NSLog(attribute);
if([att_type isEqualToString:#"positive"]) {
backpack.pos_att = [backpack.pos_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else if ([att_type isEqualToString:#"negative"]) {
backpack.neg_att = [backpack.neg_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else {
backpack.neutral_att = [backpack.neutral_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
}
}
}
else {
//we use the integer value
NSString *att_type = [[item.attributes objectAtIndex:num2] valueForKey:#"effect_type"];
NSInteger y = [[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"value"]] integerValue];
NSString *a = [NSString stringWithFormat:#"%d", y];
NSString *attribute = [[[item.attributes objectAtIndex:num2] valueForKey:#"description_string"] stringByReplacingOccurrencesOfString:#"%s1" withString:a];
if([att_type isEqualToString:#"positive"]) {
backpack.pos_att = [backpack.pos_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else if ([att_type isEqualToString:#"negative"]) {
backpack.neg_att = [backpack.neg_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else {
backpack.neutral_att = [backpack.neutral_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
}
}
}
}
}
}
}
}
[backpackItems addObject:backpack];
}
}
}
return backpackItems;
}
The actual code to set the values of the attributes:
if(![[[item.attributes objectAtIndex:num2] valueForKey:#"stored_as_integer"] boolValue]) {
//we use the float value
if([[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"float_value"]] isEqualToString:#"1"] || [[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"float_value"]] isEqualToString:#"0"]) {
//the attribute is string only, it has no values
NSString *att_type = [[item.attributes objectAtIndex:num2] valueForKey:#"effect_type"];
NSString *attribute = [[item.attributes objectAtIndex:num2] valueForKey:#"description_string"];
if([att_type isEqualToString:#"positive"]) {
backpack.pos_att = [backpack.pos_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else if ([att_type isEqualToString:#"negative"]) {
backpack.neg_att = [backpack.neg_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else {
backpack.neutral_att = [backpack.neutral_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
}
}
else {
//the attribute uses values given my the float_value key
NSString *att_type = [[item.attributes objectAtIndex:num2] valueForKey:#"effect_type"];
double y = [[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"float_value"]] doubleValue];
NSInteger z;
if([[[item.attributes objectAtIndex:num2] valueForKey:#"description_string"] rangeOfString:#"%s1%"].location != NSNotFound) {
//for values with percentages
z = lroundf(y*100);
if(z >= 100) {
z = z - 100;
}
}
else {
//for values that are just integers
z = y;
}
NSString *a = [NSString stringWithFormat:#"%d", z];
NSString *attribute = [[[item.attributes objectAtIndex:num2] valueForKey:#"description_string"] stringByReplacingOccurrencesOfString:#"%s1" withString:a];
//NSLog(attribute);
if([att_type isEqualToString:#"positive"]) {
backpack.pos_att = [backpack.pos_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else if ([att_type isEqualToString:#"negative"]) {
backpack.neg_att = [backpack.neg_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else {
backpack.neutral_att = [backpack.neutral_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
}
}
}
else {
//we use the integer value
NSString *att_type = [[item.attributes objectAtIndex:num2] valueForKey:#"effect_type"];
NSInteger y = [[NSString stringWithFormat:#"%#", [[group.attributes objectAtIndex:num] valueForKey:#"value"]] integerValue];
NSString *a = [NSString stringWithFormat:#"%d", y];
NSString *attribute = [[[item.attributes objectAtIndex:num2] valueForKey:#"description_string"] stringByReplacingOccurrencesOfString:#"%s1" withString:a];
if([att_type isEqualToString:#"positive"]) {
backpack.pos_att = [backpack.pos_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else if ([att_type isEqualToString:#"negative"]) {
backpack.neg_att = [backpack.neg_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
} else {
backpack.neutral_att = [backpack.neutral_att stringByAppendingString:[NSString stringWithFormat:#"%#\n", attribute]];
}
}
}
It seems that the problem was that my array groups.attributes containing the attributes for each item had each attribute twice, so I initialized it wrong. Thanks to everyone who helped.
Related
Right now i am using the <AddressBookUI/AddressBookUI.h>
it is working fine, it is opening the address view controller, after tapping in a contact it goes to the detail view where I can click on any property to select and get the information.
below is the code i am using right now:
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
[self peoplePickerNavigationController:peoplePicker shouldContinueAfterSelectingPerson:person property:property identifier:identifier]; }
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[picker dismissModalViewControllerAnimated:YES]; }
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
ABMutableMultiValueRef multi = ABRecordCopyValue(person, property);
CFStringRef phone1 = ABMultiValueCopyValueAtIndex(multi, identifier);
NSLog(#"phone %#", (__bridge NSString *)phone1);
CFRelease(phone1);
ABMultiValueRef fnameProperty = ABRecordCopyValue(person, kABPersonFirstNameProperty);
ABMultiValueRef lnameProperty = ABRecordCopyValue(person, kABPersonLastNameProperty);
ABMultiValueRef phoneProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
ABMultiValueRef emailProperty = ABRecordCopyValue(person, kABPersonEmailProperty);
NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
NSString *name,*phone,*email;
phone = [[NSString alloc]init];
email = [[NSString alloc]init];
name = [[NSString alloc]init];
if (fnameProperty != nil) {
name = [NSString stringWithFormat:#"%#", fnameProperty];
}
if (lnameProperty != nil) {
name = [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:#"%#,", [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++) {
email = [email stringByAppendingString:[NSString stringWithFormat:#"%#\n", [emailArray objectAtIndex:i]]];
}
}else {
email = [NSString stringWithFormat:#"%#", [emailArray objectAtIndex:0]];
}
}
//----setting txt field values
NSArray *f_name = [name componentsSeparatedByString:#" "];
if(f_name.count>1)
{
txtFirstname.text = [f_name objectAtIndex:0];
txtLastname.text = [f_name objectAtIndex:1];
}else{
txtFirstname.text = [f_name objectAtIndex:0];
}
NSArray *only_1_no = [phone componentsSeparatedByString:#","];
NSString *str = [only_1_no objectAtIndex:identifier];
NSCharacterSet *unwantedStr = [NSCharacterSet characterSetWithCharactersInString:#"+() -"];
str = [[str componentsSeparatedByCharactersInSet: unwantedStr] componentsJoinedByString: #""];
NSArray *ar = [email componentsSeparatedByString:#"\n"];
NSMutableString *abcd = [[NSMutableString alloc]init];
for (int i = 0; i<str.length; i++)
{
NSString *abc = [NSString stringWithFormat:#"%C",[phone characterAtIndex:i]];
if(i==0){
abcd =[NSMutableString stringWithFormat:#"%#",abc];
}else{
abcd = [NSMutableString stringWithFormat:#"%#%#",abcd,abc];
}
[self showmaskonnumber:abcd];
}
txtPhoneno.text = str;
txtEmail.text = [ar objectAtIndex:0];
ABPeoplePickerNavigationController *peoplePicker1 = (ABPeoplePickerNavigationController *)peoplePicker.navigationController;
[peoplePicker1 dismissModalViewControllerAnimated:YES];
[txtEmail becomeFirstResponder];
return YES;
}
my question is: Which changes should I make to this code so when I select a contact on the address list view, the selection returns the contact and all its information without showing its details?
I solved my issue by using this delegate method
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person;
{ [self selectedPerson:person]; }
I am using SQLite and I want to save the name, address, and phone text fields for them to show up in the next view controller for when the "show details" button is clicked in 1st VC.
I placed "save" and "show details" button in 1st VC, as well as "previous" and "next" button in 2nd VC. Whenever I click on "show details" I am getting this error message:
index 0 beyond bounds for empty array.
However, I see that the array is not empty. I want to store the student details in the array.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *homeDirectory = NSHomeDirectory();
NSString *documentsDirectoryPath = [homeDirectory stringByAppendingPathComponent:#"Documents"];
self.dbFilePathInDocuments = [documentsDirectoryPath stringByAppendingPathComponent:#"details.db"];
self.studentDetails = [[NSMutableArray alloc]init];
NSString *selectQuery = [NSString stringWithFormat:#"select name,address,phone from contacts"];
sqlite3_open([self.dbFilePathInDocuments UTF8String], &dataBase);
sqlite3_prepare_v2(dataBase, [selectQuery UTF8String], -1,&selectStatement, NULL);
while (sqlite3_step(selectStatement) == SQLITE_ROW)
{
NSMutableDictionary *studentDict = [[NSMutableDictionary alloc]init];
NSString *name = [NSString stringWithFormat:#"%s",sqlite3_column_text(selectStatement, 0)];
NSString *address = [NSString stringWithFormat:#"%s",sqlite3_column_text(selectStatement, 1)];
NSString *phone = [NSString stringWithFormat:#"%s",sqlite3_column_text(selectStatement, 2)];
[studentDict setObject:name forKey:#"name"];
[studentDict setObject:address forKey:#"address"];
[studentDict setObject:phone forKey:#"phone"];
[self.studentDetails addObject:studentDict];
NSLog(#"student is:%#",self.studentDetails);
}
sqlite3_finalize(selectStatement);
sqlite3_close(dataBase);
self.nameLabel.text = [[self.studentDetails objectAtIndex:0] valueForKey:#"name"];
self.addressLabel.text = [[self.studentDetails objectAtIndex:0] valueForKey:#"address"];
self.phoneLabel.text = [[self.studentDetails objectAtIndex:0] valueForKey:#"phone"];
currentStudentIndex = 0;
}
- (IBAction)clickPrevious:(id)sender {
if(currentStudentIndex <=0)
{
currentStudentIndex = 0;
}else
{
currentStudentIndex = currentStudentIndex - 1;
}
self.nameLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"name"];
self.addressLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"address"];
self.phoneLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"phone"];
}
- (IBAction)clickNext:(id)sender {
if(currentStudentIndex >= [self.studentDetails count] - 1)
{
currentStudentIndex = [self.studentDetails count] - 1;
}else
{
currentStudentIndex = currentStudentIndex + 1;
}
self.nameLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"name"];
self.addressLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"address"];
self.phoneLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"phone"];
}
The issue is that you always accessing the array self.studentDetails even if it's empty. This will cause an exception.
First limit setting of the labels to a single method and check the array access will succeed before attempting it:
- (void)updateLabels
{
if (currentStudentIndex >= [self.studentDetails count])
return;
self.nameLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"name"];
self.addressLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"address"];
self.phoneLabel.text = [[self.studentDetails objectAtIndex:currentStudentIndex] valueForKey:#"phone"];
}
and use that method in the 3 places you currently set the labels. For example:
- (IBAction)clickPrevious:(id)sender {
currentStudentIndex--;
[self updateLabels];
}
- (IBAction)clickNext:(id)sender {
currentStudentIndex++;
[self updateLabels];
}
In the viewDidLoad method use this code:
...
sqlite3_finalize(selectStatement);
sqlite3_close(dataBase);
currentStudentIndex = 0;
[self updateLabels];
After that you're gonna want to work on enabling/disabling buttons depending on whether there is a next or previous student to view to make using the app more intuitive.
I have an NSMuableArray with each string containing lots of information(i know its not the best way but its how I'm doing it) so each string looks something like
02:00:00-21:00:00-June 3th, 2014-23:00:00-June 3th, 2014||VincentKahn.com||10.00
I want to sort it by the first date, the 21:00:00-June 3th, 2014 part (i know there are typos), I've seen examples of NSSortDescriptor but i don't just have a date, and i still need to retain all of the information.
I've tried splitting it but that was in a for each loop and if i did it how i know i will loose the formatting which i need.
What's the quickest way to do Sort this?
If it helps i'm sorting it for a TableView
EDIT:
I'm retrieving these strings saved in a .plist opened into a mutable array
Complicated Approach, but i ended up using a triple sorted system using blocks (i think thats the name) Sorted the day, then the month then the year.
-(void)sortTable {
NSString *Ja = #"January";
NSString *Fe = #"February";
NSString *Ma = #"March";
NSString *Ap = #"April";
NSString *Mar = #"May";
NSString *Ju = #"June";
NSString *Jul = #"July";
NSString *Au = #"August";
NSString *Se = #"September";
NSString *Oc = #"October";
NSString *No = #"November";
NSString *De = #"December";
NSArray *sortedDay = [arrayFromPlist sortedArrayUsingComparator:^NSComparisonResult(id a, id b)
{
NSString *aString = (NSString*) a;
NSString *dateA = [[aString componentsSeparatedByString:#"-"] objectAtIndex:2];
NSString *thePreDayA = [[dateA componentsSeparatedByString:#" "] objectAtIndex:1];
NSString *almostDayA = [[thePreDayA componentsSeparatedByString:#","] objectAtIndex:0];
if ([almostDayA rangeOfString:#"th"].location != NSNotFound) {
NSLog (#"Yes, we have a th at location %i", [almostDayA rangeOfString:#"th"].location );
theDayA = [[almostDayA componentsSeparatedByString:#"th"] objectAtIndex:0];
} else {
theDayA = almostDayA;
}
int aInt = [theDayA integerValue];
NSString *bString = (NSString*) b;
NSString *dateB = [[bString componentsSeparatedByString:#"-"] objectAtIndex:2];
NSString *thePreDayB = [[dateB componentsSeparatedByString:#" "] objectAtIndex:1];
NSString *almostDayB = [[thePreDayB componentsSeparatedByString:#","] objectAtIndex:0];
if ([almostDayB rangeOfString:#"th"].location != NSNotFound) {
NSLog (#"Yes, we have a th at location %i", [almostDayB rangeOfString:#"th"].location );
theDayB = [[almostDayB componentsSeparatedByString:#"th"] objectAtIndex:0];
} else {
theDayB = almostDayB;
}
int bInt = [theDayB integerValue];
return aInt > bInt;
}];
NSArray *sortedMonths = [sortedDay sortedArrayUsingComparator:^NSComparisonResult (id a, id b)
{
NSString *aString = (NSString*) a;
NSString *dateA = [[aString componentsSeparatedByString:#"-"] objectAtIndex:2];
NSString * preMonthA = [[dateA componentsSeparatedByString:#" "] objectAtIndex:0];
int aInt;
if([preMonthA isEqualToString:Ja]) {
aInt = 1;
} else if([preMonthA isEqualToString:Fe]) {
aInt = 2;
} else if([preMonthA isEqualToString:Mar]) {
aInt = 3;
} else if([preMonthA isEqualToString:Ap]) {
aInt = 4;
} else if([preMonthA isEqualToString:Ma]) {
aInt = 5;
} else if([preMonthA isEqualToString:Ju]) {
aInt = 6;
} else if([preMonthA isEqualToString:Jul]) {
aInt = 7;
} else if([preMonthA isEqualToString:Au]) {
aInt = 8;
} else if([preMonthA isEqualToString:Se]) {
aInt = 9;
} else if([preMonthA isEqualToString:Oc]) {
aInt = 10;
} else if([preMonthA isEqualToString:No]) {
aInt = 11;
} else if([preMonthA isEqualToString:De]) {
aInt = 12;
} else {
aInt = 0;
}
NSString *bString = (NSString*) b;
NSString *dateB = [[bString componentsSeparatedByString:#"-"] objectAtIndex:2];
NSString *preMonthB = [[dateB componentsSeparatedByString:#" "] objectAtIndex:0];
int bInt;
if([ preMonthB isEqualToString:Ja]) {
bInt = 1;
} else if([ preMonthB isEqualToString:Fe]) {
bInt = 2;
} else if([ preMonthB isEqualToString:Mar]) {
bInt = 3;
} else if([ preMonthB isEqualToString:Ap]) {
bInt = 4;
} else if([ preMonthB isEqualToString:Ma]) {
bInt = 5;
} else if([ preMonthB isEqualToString:Ju]) {
bInt = 6;
} else if([ preMonthB isEqualToString:Jul]) {
bInt = 7;
} else if([ preMonthB isEqualToString:Au]) {
bInt = 8;
} else if([ preMonthB isEqualToString:Se]) {
bInt = 9;
} else if([ preMonthB isEqualToString:Oc]) {
bInt = 10;
} else if([ preMonthB isEqualToString:No]) {
bInt = 11;
} else if([ preMonthB isEqualToString:De]) {
bInt = 12;
} else {
bInt = 0;
}
return aInt > bInt;
}];
NSArray *sortedYear = [sortedMonths sortedArrayUsingComparator:^NSComparisonResult(id a, id b)
{
NSString *aString = (NSString*) a;
NSString *dateA = [[aString componentsSeparatedByString:#"-"] objectAtIndex:2];
int aInt = [[[dateA componentsSeparatedByString:#" "] objectAtIndex:2] integerValue];
NSString *bString = (NSString*) b;
NSString *dateB = [[bString componentsSeparatedByString:#"-"] objectAtIndex:2];
int bInt = [[[dateB componentsSeparatedByString:#" "] objectAtIndex:2] integerValue];
return aInt > bInt;
}];
NSLog(#"SORTED ARRRAYYYYYYYY: %#", sortedYear);
}
I was looking into implementing hashtag autocomplete with objective-C as shown in the picture
I found it a bit difficult than expected. I'm looking more specific implementation for adding and deleting hashtags. For example, the hashtag should be deleted as a whole at once. I was wondering if anyone has similar experience implemented it and if there's a more efficient way implemented it. Thanks
I ended up writing some functions that I feel is a bit ugly but it works. Maybe there are some more efficient ways to implement it.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//user is a singleton instance
User *user = [User sharedUser];
user.autocompleteTableView.hidden = NO;
int identifiedTagsStringLength = [self.identifiedTagsString length];
int cursorLocation = range.location;
//insert characters
if (range.location >= identifiedTagsStringLength) {
NSString *newSearch =#"";
NSRange newRange;
if(identifiedTagsStringLength != 0) {
newSearch = [urlField.text substringFromIndex:identifiedTagsStringLength];
newRange = NSMakeRange(range.location - identifiedTagsStringLength, 0);
}
else {
newSearch = textField.text;
newRange = range;
}
NSString *substring = [NSString stringWithString:newSearch];
substring = [substring stringByReplacingCharactersInRange:newRange withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
if (cursorLocation > currentTagsRange) {
currentTagsRange = cursorLocation;
}
}
//delete tags
else {
if ([self.ranges count] != 0 && cursorLocation < currentTagsRange) {
int rangeLength = [self.ranges count];
int toBeRemovedIndex = 0;
for (int i = 0; i< rangeLength; i++) {
if (cursorLocation >= [[self.ranges objectAtIndex:i][0] intValue]
&& cursorLocation <= [[self.ranges objectAtIndex:i][1] intValue]) {
toBeRemovedIndex = i;
}
}
[self.tags removeObjectAtIndex:toBeRemovedIndex];
[self updateRanges];
NSString *outputString = #"";
for (NSString *tag in self.tags) {
outputString = [NSString stringWithFormat:#"%##%# ", outputString,
tag];
}
urlField.text = outputString;
self.identifiedTagsString = urlField.text;
currentTagsRange = [outputString length] - 1;
}
}
return YES;
}
- (void)updateRanges {
self.ranges = [[NSMutableArray alloc] init];
int startIndex = 0;
for (NSString *tag in self.tags) {
startIndex = [self.ranges count] == 0 ? 0 : [[self.ranges lastObject][1] intValue] + 1;
int tagLength = [tag length];
NSArray *range = [NSArray arrayWithObjects:[NSNumber numberWithInt:startIndex], [NSNumber numberWithInt:startIndex + tagLength + 1], nil];
[self.ranges addObject: range];
}
}
#pragma mark UITableViewDataSource methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (self.identifiedTagsString == NULL) {
self.identifiedTagsString = #"";
}
[self.tags addObject: selectedCell.textLabel.text];
[self updateRanges];
NSString *output = #"";
for (NSString *tag in self.tags) {
output = [NSString stringWithFormat:#"%##%# ", output, tag];
}
urlField.text = output;
User *user = [User sharedUser];
user.autocompleteTableView.hidden = YES;
self.identifiedTagsString = urlField.text;
currentTagsRange = [urlField.text length];
}
I have array of dictionary values and have implemented the counter method for individual array items but had problem with getting the final counter values. it was adding individual counter values.
here is the source code.
-(void)getData
{
[lReportArr removeAllObjects];
lMetaCount = 0;
NSMutableArray *lTempArr = [[NSMutableArray alloc] initWithArray:lMetaArray];
NSLog(#"Metabolic Array:-%#", lTempArr);
for (int i = 0; i < [lTempArr count]; i++)
{
NSMutableDictionary *lDict = [lTempArr objectAtIndex:i];
NSString *lTitle = [lDict objectForKey:#"title"];
//Glucose Low count
if ([lTitle rangeOfString:#"Glucose reading : Low"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"Low BG:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
//Glucose High count
else if ([lTitle rangeOfString:#"Glucose reading : High"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"High BG:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
//Wrong Dose Cause count
else if([lTitle rangeOfString:#"Low Cause: Wrong Dose"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"LG Wrong Dose:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
else if([lTitle rangeOfString:#"High Cause: Wrong Dose"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"HG Wrong Dose:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
//Symptoms Cause count
else if([lTitle rangeOfString:#"Low Cause: Illness"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"LG Illness:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
else if([lTitle rangeOfString:#"High Cause: Illness"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"HG Symptoms:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
//LG n HG Treatment count
else if([lTitle rangeOfString:#"Treatment: Emergency Room"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"Emergency Room:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
else if([lTitle rangeOfString:#"Treatment: Hospitalization"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"Hospitalization:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
else if([lTitle rangeOfString:#"Treatment: Extra MD Office"].length > 0)
{
lMetaCount++;
NSString *lCount = [NSString stringWithFormat:#"Extra MD Office:%d",lMetaCount];
[lDict setValue:lCount forKey:#"metabolicCount"];
}
[lReportArr addObject:lDict];
}
}
you can use
int c = [[lReportArr objectAtIndex:0] valueForKey:#"metabolicCount"];
this will give you the final count of metabolicCount value for first object stored in dictionary if it contains metabolicCount key