My issue is only with my picker "proPicker." The weird thing is, the objects are still in the array, as the text in my textfield changes even though the picker shows up blank....
I believe I have followed all of the steps to populate the picker, and 9 out of 10 times the picker shows the correct information, but sometimes it just shows up blank..
Here is my code:
.h:
//
// EditDebateViewController.h
//
//
// Created by Jacob Klapper on 10/17/13.
//
//
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface EditDebateViewController : UITableViewController <UITextFieldDelegate, UIPickerViewDelegate,UIActionSheetDelegate>
#property UIDatePicker *pickerView;
#property (weak, nonatomic) IBOutlet UITextField *topic;
#property (weak, nonatomic) IBOutlet UITextField *pro;
#property (weak, nonatomic) IBOutlet UITextField *con;
#property (weak, nonatomic) IBOutlet UITextField *pVotes;
#property (weak, nonatomic) IBOutlet UITextField *cVotes;
#property (weak, nonatomic) IBOutlet UITextField *abs;
#property (weak, nonatomic) IBOutlet UITextField *date;
#property NSMutableArray *pChoices;
#property NSMutableArray *pStrings;
#property NSMutableArray *cChoices;
#property NSMutableArray *cStrings;
#property NSMutableArray *proTest;
#property UIPickerView *proPicker;
#property PFObject *obj;
#end
.m:
//
// EditDebateViewController.m
//
//
// Created by Jacob Klapper on 10/17/13.
//
//
#import "EditDebateViewController.h"
#interface EditDebateViewController ()
#end
#implementation EditDebateViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//self.date = [[UIDatePicker alloc]init];
self.date.delegate = self;
self.pro.delegate = self;
self.con.delegate = self;
self.pVotes.delegate = self;
self.cVotes.delegate = self;
self.abs.delegate = self;
self.topic.delegate = self;
self.pickerView = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 322, 0, 0)];
self.pickerView.datePickerMode = UIDatePickerModeDate;
self.pickerView.hidden = true;
self.pickerView.date = [NSDate date];
[self.pickerView addTarget:self
action:#selector(updateLabel:)
forControlEvents:UIControlEventValueChanged];
//[self.view addSubview:pickerToolbar];
[self.tableView addSubview:self.pickerView];
//self.pickerView.del
self.date.inputView = self.pickerView;
NSDateFormatter *df = [[NSDateFormatter alloc] init];
//[df setLocale:enUSPOSIXLocale];
[df setTimeZone:[NSTimeZone systemTimeZone]];
[df setDateFormat:#"MMM dd, yyyy "];
self.proPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 322, 0, 0)];
self.proPicker.hidden = true;
self.proPicker.delegate = self;
[self.tableView addSubview:self.proPicker];
self.pro.inputView = self.proPicker;
self.pStrings = [[NSMutableArray alloc]init];
self.cStrings = [[NSMutableArray alloc]init];
self.pChoices = [[NSMutableArray alloc]initWithArray:[self.obj objectForKey:#"PR"]];
self.cChoices = [[NSMutableArray alloc]init];
self.proTest = [[NSMutableArray alloc]init];
//self.pChoices = [self.obj objectForKey:#"PR"];
//self.cChoices = [self.obj objectForKey:#"CR"];
NSLog(#"Choices Now: %#", self.pChoices);
NSLog(#"Choices Count: %lu", (unsigned long)[self.pChoices count]);
for (PFUser *us in self.pChoices) {
//NSLog(#"Hi");
//PFUser *user = [self.pChoices objectAtIndex:i];
[us fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
//[self.pChoices addObject:object];
//NSString *name = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
//NSLog(name);
//[self.proTest addObject:object];
//NSLog(#"The value before pStrings is: %#", name);
//[self.pStrings addObject:name];
//NSLog(#"This is spot: %#", [self.pStrings objectAtIndex:i]);
[self.proTest addObject:object];
NSString *name = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
[self.pStrings addObject:name];
NSLog(#"Pro Test: %#", self.proTest);
NSLog(#"Pro Strings: %#", self.pStrings);
NSLog(#"User: %#", us);
NSLog(#"Object: %#", object);
}];
}
NSLog(#"Strings: %#", self.pStrings);
NSLog(#"Pro Test: %lu", (unsigned long)[self.proTest count]);
//NSLog(#"%#", self.pStrings);
self.topic.text = [self.obj objectForKey:#"Topic"];
self.date.text = [df stringFromDate:[self.obj objectForKey:#"Date"]];
NSLog(#"Hi Test");
if([[NSString stringWithFormat:#"%#", [self.obj objectForKey:#"proVotes"] ] isEqualToString:#"0"])
{
NSLog(#"ITS NULL");
self.pVotes.text = #"";
}
//self.pVotes.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"proVotes"] ];
else
{
self.pVotes.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"proVotes"] ];
}
if([[NSString stringWithFormat:#"%#", [self.obj objectForKey:#"conVotes"] ] isEqualToString:#"0"])
{
self.cVotes.text = #"";
}
else
{
self.cVotes.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"conVotes"] ];
}
if([[NSString stringWithFormat:#"%#", [self.obj objectForKey:#"Abstentions"] ] isEqualToString:#"0"])
{
self.abs.text = #"";
}
else
{
self.abs.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"Abstentions"]];
}
/*
NSLog(#"Here");
NSLog(#"%#", proU);
self.pro.text = [NSString stringWithFormat:#"%# %#", [proU objectForKey:#"firstName"], [proU objectForKey:#"lastName"]];
PFUser *conU = [self.obj objectForKey:#"Con"];
//self.con.text = [NSString stringWithFormat:#"%# %#", [conU objectForKey:#"firstName"], [conU objectForKey:#"lastName"]];
*/
PFUser *proU = [self.obj objectForKey:#"Pro"];
[proU fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
self.pro.text = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
}];
PFUser *conU = [self.obj objectForKey:#"Con"];
[conU fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
self.con.text = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
}];
[self.pickerView setDate:[self.obj objectForKey:#"Date"]];
[self.proPicker reloadAllComponents];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated
{
[self.proPicker reloadAllComponents];
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)backcustom:(UIBarButtonItem *)sender {
[self.navigationController popViewControllerAnimated:YES];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//[aTextField resignFirstResponder];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
//[df setLocale:enUSPOSIXLocale];
[df setTimeZone:[NSTimeZone systemTimeZone]];
[df setDateFormat:#"MMM dd, yyyy "];
if(textField == self.topic)
{
NSLog(#"Topic");
}
if(textField == self.date)
{
self.pickerView.hidden = false;
self.date.text = [df stringFromDate:self.pickerView.date];
}
if(textField == self.pro)
{
self.proPicker.hidden = false;
//self.pro.text =
NSInteger rowSelectionKg = [self.proPicker selectedRowInComponent:0]; //get currrent row of picker for first column
NSString *tempKg = [self.pStrings objectAtIndex:rowSelectionKg]; //use row as index to get value in corresponding array of choices in picker
self.pro.text = tempKg;
}
//pickerViewPopup = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
return YES;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (pickerView == self.proPicker) {
self.pro.text = [self.pStrings objectAtIndex:row];
}
else
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
//[df setLocale:enUSPOSIXLocale];
[df setTimeZone:[NSTimeZone systemTimeZone]];
[df setDateFormat:#"MMM dd, yyyy "];
self.date.text = [df stringFromDate:self.pickerView.date];
//NSString *strFirstPickerView = [_ty objectAtIndex:row];
//_providerType.text = strFirstPickerView;
}
}
- (void)updateLabel:(id)sender {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
//[df setLocale:enUSPOSIXLocale];
[df setTimeZone:[NSTimeZone systemTimeZone]];
[df setDateFormat:#"MMM dd, yyyy "];
self.date.text = [df stringFromDate:self.pickerView.date];
}
- (IBAction)saveChanges:(UIBarButtonItem *)sender {
[self.obj setObject:self.topic.text forKey:#"Topic"];
[self.obj setObject:[NSNumber numberWithInt:self.pVotes.text.intValue] forKey:#"proVotes"];
[self.obj setObject:[NSNumber numberWithInt:self.cVotes.text.intValue] forKey:#"conVotes"];
[self.obj setObject:[NSNumber numberWithInt:self.abs.text.intValue] forKey:#"Abstentions"];
[self.obj setObject:self.pickerView.date forKey:#"Date"];
NSLog(#"Saving...");
[self.obj saveInBackground];
[self performSegueWithIdentifier:#"afterSave" sender:self];
//[self.navigationController popViewControllerAnimated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Section: %ld", (long)[indexPath section]);
NSLog(#"Row: %ld", (long)[indexPath row]);
if([indexPath section] == 1 && [indexPath row] == 0)
{
NSLog(#"Right Cell");
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Delete Debate" otherButtonTitles:nil];
popupQuery.tag = 1;
[popupQuery showInView:self.view];
}
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(actionSheet.tag == 1)
{
if(buttonIndex == 0)
{
[self.obj deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[self performSegueWithIdentifier:#"afterSave" sender:self];
//[self loadObjects];
}];
}
}
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
if(pickerView == self.proPicker)
{
NSLog(#"First Log");
NSLog(#"In numComponents: %#",self.pStrings);
return 1;
}
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
if(pickerView == self.proPicker)
{
NSLog(#"Right Picker");
NSLog(#"Count in numRows: %lu", (unsigned long)[self.pStrings count]);
return [self.pStrings count];
}
//return [_ty count];
return [self.pStrings count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if(pickerView == self.proPicker)
{
NSLog(#"Picked goooood");
return [self.pStrings objectAtIndex:row];
}
return [self.pStrings objectAtIndex:row];
}
#end
The fetchIfNeededInBackgroundWithBlock call is asynchronous.
This line:
[self.pStrings addObject:name];
fills in the data into self.pStrings.
You are expecting its values to be filled in by the time you hit this call:
[self.proPicker reloadAllComponents];
at the end of your viewDidLoad method. You somehow need to not reloadAllComponents until that data is loaded.
I would recommend adding a BOOL to track if you've already reloaded the components. If you have, just do it again at the end of fetching the data. Like this:
- (void)viewDidLoad
{
[super viewDidLoad];
__block BOOL hasCompletedSetup = NO;
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//self.date = [[UIDatePicker alloc]init];
self.date.delegate = self;
self.pro.delegate = self;
self.con.delegate = self;
self.pVotes.delegate = self;
self.cVotes.delegate = self;
self.abs.delegate = self;
self.topic.delegate = self;
self.pickerView = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 322, 0, 0)];
self.pickerView.datePickerMode = UIDatePickerModeDate;
self.pickerView.hidden = true;
self.pickerView.date = [NSDate date];
[self.pickerView addTarget:self
action:#selector(updateLabel:)
forControlEvents:UIControlEventValueChanged];
//[self.view addSubview:pickerToolbar];
[self.tableView addSubview:self.pickerView];
//self.pickerView.del
self.date.inputView = self.pickerView;
NSDateFormatter *df = [[NSDateFormatter alloc] init];
//[df setLocale:enUSPOSIXLocale];
[df setTimeZone:[NSTimeZone systemTimeZone]];
[df setDateFormat:#"MMM dd, yyyy "];
self.proPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 322, 0, 0)];
self.proPicker.hidden = true;
self.proPicker.delegate = self;
[self.tableView addSubview:self.proPicker];
self.pro.inputView = self.proPicker;
self.pStrings = [[NSMutableArray alloc]init];
self.cStrings = [[NSMutableArray alloc]init];
self.pChoices = [[NSMutableArray alloc]initWithArray:[self.obj objectForKey:#"PR"]];
self.cChoices = [[NSMutableArray alloc]init];
self.proTest = [[NSMutableArray alloc]init];
//self.pChoices = [self.obj objectForKey:#"PR"];
//self.cChoices = [self.obj objectForKey:#"CR"];
NSLog(#"Choices Now: %#", self.pChoices);
NSLog(#"Choices Count: %lu", (unsigned long)[self.pChoices count]);
for (PFUser *us in self.pChoices) {
//NSLog(#"Hi");
//PFUser *user = [self.pChoices objectAtIndex:i];
[us fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
//[self.pChoices addObject:object];
//NSString *name = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
//NSLog(name);
//[self.proTest addObject:object];
//NSLog(#"The value before pStrings is: %#", name);
//[self.pStrings addObject:name];
//NSLog(#"This is spot: %#", [self.pStrings objectAtIndex:i]);
[self.proTest addObject:object];
NSString *name = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
[self.pStrings addObject:name];
NSLog(#"Pro Test: %#", self.proTest);
NSLog(#"Pro Strings: %#", self.pStrings);
NSLog(#"User: %#", us);
NSLog(#"Object: %#", object);
}];
if (hasCompletedSetup) {
[self.proPicker reloadAllComponents];
}
}
NSLog(#"Strings: %#", self.pStrings);
NSLog(#"Pro Test: %lu", (unsigned long)[self.proTest count]);
//NSLog(#"%#", self.pStrings);
self.topic.text = [self.obj objectForKey:#"Topic"];
self.date.text = [df stringFromDate:[self.obj objectForKey:#"Date"]];
NSLog(#"Hi Test");
if([[NSString stringWithFormat:#"%#", [self.obj objectForKey:#"proVotes"] ] isEqualToString:#"0"])
{
NSLog(#"ITS NULL");
self.pVotes.text = #"";
}
//self.pVotes.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"proVotes"] ];
else
{
self.pVotes.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"proVotes"] ];
}
if([[NSString stringWithFormat:#"%#", [self.obj objectForKey:#"conVotes"] ] isEqualToString:#"0"])
{
self.cVotes.text = #"";
}
else
{
self.cVotes.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"conVotes"] ];
}
if([[NSString stringWithFormat:#"%#", [self.obj objectForKey:#"Abstentions"] ] isEqualToString:#"0"])
{
self.abs.text = #"";
}
else
{
self.abs.text = [NSString stringWithFormat:#"%#", [self.obj objectForKey:#"Abstentions"]];
}
/*
NSLog(#"Here");
NSLog(#"%#", proU);
self.pro.text = [NSString stringWithFormat:#"%# %#", [proU objectForKey:#"firstName"], [proU objectForKey:#"lastName"]];
PFUser *conU = [self.obj objectForKey:#"Con"];
//self.con.text = [NSString stringWithFormat:#"%# %#", [conU objectForKey:#"firstName"], [conU objectForKey:#"lastName"]];
*/
PFUser *proU = [self.obj objectForKey:#"Pro"];
[proU fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
self.pro.text = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
}];
PFUser *conU = [self.obj objectForKey:#"Con"];
[conU fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
self.con.text = [NSString stringWithFormat:#"%# %#", [object objectForKey:#"firstName"], [object objectForKey:#"lastName"]];
}];
[self.pickerView setDate:[self.obj objectForKey:#"Date"]];
hasCompletedSetup = YES;
[self.proPicker reloadAllComponents];
}
Related
I have added search bar for collection view using programatically .But when i enter the names to search nothing shows.I have some section also and each section contains some data.
Here is my code:
#interface ViewController ()
{
NSMutableArray *arrayPDFName;
NSMutableArray *titleArray;
}
#property (nonatomic,strong) NSArray *dataSourceForSearchResult;
#property (nonatomic) BOOL searchBarActive;
#property (nonatomic) float searchBarBoundsY;
#property (nonatomic,strong) UISearchBar *searchBar;
#property (nonatomic,strong) UIRefreshControl *refreshControl;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataSourceForSearchResult = [NSArray new];
titleArray = [NSMutableArray array];
[self getdata];
self.mycollectionView.dataSource = self;
self.mycollectionView.delegate = self;
[self.mycollectionView reloadData];
}
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:#"%02x",result[i]];
}
return ret;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self prepareUI];
}
-(void)getdata {
NSString *userName = #“username#yahoo.com";
NSString *password = #“password”;
NSData *plainData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://api.exampleport/user/orderid/files";
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
// basic authendication
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
//header-field
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64Encoding]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError * error;
self->arrayPDFName = [[NSMutableArray alloc]init];
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dictOriginal = jsonResults[#“dark”];
[titleArray addObject:[NSString stringWithFormat:#"dark(%#)”, dictOriginal[#"count"]]];
NSDictionary *dictOriginal2 = jsonResults[#"orange”];
[titleArray addObject:[NSString stringWithFormat:#"orange(%#)”, dictOriginal2[#"count"]]];
NSDictionary *dictOriginal3 = jsonResults[#"pencill”];
[titleArray addObject:[NSString stringWithFormat:#"pencill(%#)”, dictOriginal3[#"count"]]];
NSDictionary *dictOriginal4 = jsonResults[#"smart”];
[titleArray addObject:[NSString stringWithFormat:#"smart(%#)”, dictOriginal4[#"count"]]];
NSArray *arrayFiles = [NSArray arrayWithObjects: dictOriginal, dictOriginal2, dictOriginal3, dictOriginal4, nil];
NSLog(#"str: %#", titleArray);
for (NSDictionary *dict in arrayFiles) {
NSMutableArray *arr = [NSMutableArray array];
NSArray *a = dict[#"files"];
for(int i=0; i < a.count; i ++) {
NSString *strName = [NSString stringWithFormat:#"%#",[[dict[#"files"] objectAtIndex:i] valueForKey:#"name"]];
// NSLog(#"str: %#", strName);
[arr addObject:strName];
}
[arrayPDFName addObject:arr];
}
//Get plist path
NSString *errorDesc;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory1 stringByAppendingPathComponent:#"SampleData.plist"];
//NSLog(#"plistPath : %#",plistPath);
//Save data from json to plist
NSString *error1;
returnData = [NSPropertyListSerialization dataFromPropertyList:jsonResults
format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
if(returnData ) {
if ([returnData writeToFile:plistPath atomically:YES]) {
NSLog(#"Data successfully saved.");
}else {
NSLog(#"Did not managed to save NSData.");
}
}
else {
NSLog(#"%#",errorDesc);
}
// NSArray *stringsArray = [NSArray arrayWithContentsOfFile:plistPath];
NSDictionary *stringsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
// NSLog(#"str: %#", stringsDictionary);
}
//delegate method for header
-(UICollectionReusableView*) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
HeaderView * header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"myHeader" forIndexPath:indexPath];
header.myHeaderLabel.text = titleArray[indexPath.section];
return header;
}
#pragma mark - UICollectionView Datasource
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return titleArray.count;
}
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.searchBarActive) {
return self.dataSourceForSearchResult.count;
}
NSArray *a = arrayPDFName[section];
if (a.count == 0)
{
return 1;
}
else
{
return a.count;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return CGSizeMake(0, 80);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath: (NSIndexPath *)indexPath {
VenueCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"mycell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.imgV.image = [UIImage imageNamed:#"doc1.png"];
if (self.searchBarActive) {
cell.myLabel.text = _dataSourceForSearchResult[indexPath.section][indexPath.row];
}else{
NSArray *a = arrayPDFName[indexPath.section];
if (a.count == 0) {
cell.myLabel.text = #"NO DATA";
return cell;
}
cell.myLabel.text = a[indexPath.row];
}
return cell;
}
//////////////////////////for search bar //////////
#pragma mark - actions
-(void)refreashControlAction{
[self cancelSearching];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// stop refreshing after 2 seconds
[self.mycollectionView reloadData];
[self.refreshControl endRefreshing];
});
}
#pragma mark - search
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"self contains[c] %#", searchText];
self.dataSourceForSearchResult = [self->arrayPDFName filteredArrayUsingPredicate:resultPredicate];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
// user did type something, check our datasource for text that looks the same
if (searchText.length>0) {
// search and reload data source
self.searchBarActive = YES;
[self filterContentForSearchText:searchText
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
[self.mycollectionView reloadData];
}else{
// if text lenght == 0
// we will consider the searchbar is not active
self.searchBarActive = NO;
}
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[self cancelSearching];
[self.mycollectionView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
self.searchBarActive = YES;
[self.view endEditing:YES];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
// we used here to set self.searchBarActive = YES
// but we'll not do that any more... it made problems
// it's better to set self.searchBarActive = YES when user typed something
[self.searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
// this method is being called when search btn in the keyboard tapped
// we set searchBarActive = NO
// but no need to reloadCollectionView
self.searchBarActive = NO;
[self.searchBar setShowsCancelButton:NO animated:YES];
}
-(void)cancelSearching{
self.searchBarActive = NO;
[self.searchBar resignFirstResponder];
self.searchBar.text = #"";
}
#pragma mark - prepareVC
-(void)prepareUI{
[self addSearchBar];
[self addRefreshControl];
}
-(void)addSearchBar{
if (!self.searchBar) {
self.searchBarBoundsY = self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height;
self.searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,self.searchBarBoundsY, [UIScreen mainScreen].bounds.size.width, 50)];
self.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.searchBar.tintColor = [UIColor whiteColor];
self.searchBar.barTintColor = [UIColor whiteColor];
self.searchBar.delegate = self;
self.searchBar.placeholder = #"Search here";
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor whiteColor]];
// add KVO observer.. so we will be informed when user scroll colllectionView
[self addObservers];
}
if (![self.searchBar isDescendantOfView:self.view]) {
[self.view addSubview:self.searchBar];
}
}
-(void)addRefreshControl{
if (!self.refreshControl) {
self.refreshControl = [UIRefreshControl new];
self.refreshControl.tintColor = [UIColor whiteColor];
[self.refreshControl addTarget:self
action:#selector(refreashControlAction)
forControlEvents:UIControlEventValueChanged];
}
if (![self.refreshControl isDescendantOfView:self.mycollectionView]) {
[self.mycollectionView addSubview:self.refreshControl];
}
}
-(void)startRefreshControl{
if (!self.refreshControl.refreshing) {
[self.refreshControl beginRefreshing];
}
}
Where i am doing mistake and what i need to change to work.Thanks in advance!
It seems your arrayPDFName have array object and each array object have string object. There are two ways to filter you array.
Way - 1
If you want to get the list of array which has the search string the use SUBQUERY with your predicate. Like below.
NSArray *a1 = #[#"a1", #"a2", #"a3"];
NSArray *a2 = #[#"a1", #"a2", #"a3"];
NSArray *a3 = #[#"a1", #"a2", #"a3"];
NSArray *a4 = #[#"a2", #"a3"];
NSArray *allA = #[a1, a2, a3, a4];
NSPredicate *pre = [NSPredicate predicateWithFormat:#"SUBQUERY(SELF, $a, $a == %#).#count > 0", #"a1"];
NSArray *a = [allA filteredArrayUsingPredicate:pre];
Way - 2
If you want to get the search string alone from each array object then follow the below,
NSMutableArray *fa = [[NSMutableArray alloc] init];
for (NSArray *a in allA) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"self CONTAINS[c] %#", #"a3"];
[fa addObjectsFromArray:[a filteredArrayUsingPredicate:p]];
}
Note: Above code done with same sample data. Replace it as you want.
As per your code replace the below code
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
NSMutableArray *fa = [[NSMutableArray alloc] init];
for (NSArray *a in arrayPDFName) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"self CONTAINS[c] %#", searchText];
[fa addObjectsFromArray:[a filteredArrayUsingPredicate:p]];
}
self.dataSourceForSearchResult = [NSArray arrayWithArray:fa];
}
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
if(self.searchBarActive)
return 1;
return titleArray.count;
}
In cellForItemAtIndexPath
cell.myLabel.text = _dataSourceForSearchResult[indexPath.row];
I used json parsing and managed to fetch information from a website and show it in the Table View. I managed to set up the search bar such that it searches for the text. However when i key in my second letter there is nothing in the table view even though there is words starting with the two letters. I have added my code below.
#implementation EventsTableViewController
#synthesize searchBar, filteredEventsArray, eventNamesArray, isFiltered, eventsDictionary;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.eventNamesArray = [NSMutableArray array];
self.eventsDictionary = [NSMutableDictionary dictionary];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self searchForEvents];
}
//Json Parsing
- (void)searchForEvents
{
NSString *eventsSearchUrlString = [NSString stringWithFormat:#"https://www.googleapis.com/blogger/v3/blogs/1562818803553764290/posts?key=AIzaSyBTOxz-vPHgzIkw9k88hDKd99ILTaXTt0Y"];
NSURL *eventsSearchUrl = [NSURL URLWithString:eventsSearchUrlString];
NSURLRequest *eventsSearchUrlRequest = [NSURLRequest requestWithURL:eventsSearchUrl];
NSURLSession *sharedUrlSession = [NSURLSession sharedSession];
NSURLSessionDataTask *searchEventsTask =
[sharedUrlSession dataTaskWithRequest:eventsSearchUrlRequest completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
dispatch_async(dispatch_get_main_queue(),
^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if(error)
{
UIAlertView *searchAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please check your internet connection" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[searchAlertView show];
}
else
{
NSString *resultString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Search results: %#", resultString);
NSError *jsonParseError = nil;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if(jsonParseError)
{
UIAlertView *jsonParseErrorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:jsonParseError.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[jsonParseErrorAlert show];
}
else
{
for(NSString *key in jsonDictionary.keyEnumerator)
{
NSLog(#"First level key: %#", key);
}
[self.eventNamesArray removeAllObjects];
[self.eventsDictionary removeAllObjects];
NSArray *searchResultsArray = [jsonDictionary objectForKey:#"items"];
//NSLog(#"test%#",searchResultsArray);
for(NSDictionary *eventsInfoDictionary in searchResultsArray)
{
Events *event = [[Events alloc] init];
event.eventName = [eventsInfoDictionary objectForKey:#"title"];
event.eventDescription =[eventsInfoDictionary objectForKey:#"content"];
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
NSString *eventsAsStrings = [event.eventName substringToIndex:1];
NSMutableArray *eventsInArray = [self.eventsDictionary objectForKey:eventsAsStrings];
if(!eventsInArray)
{
eventsInArray = [NSMutableArray array];
[self.eventNamesArray addObject:eventsAsStrings];
}
[eventsInArray addObject:event];
[self.eventsDictionary setObject:eventsInArray forKey:eventsAsStrings];
if ([event.eventDescription containsString:#"<br />"]) {
NSString* eventDescrip = event.eventDescription;
NSString* stringWithoutHTMLtags = [eventDescrip stringByReplacingOccurrencesOfString:#"<br />" withString:#""];
event.eventDescription = stringWithoutHTMLtags;
}
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
}
[self.eventNamesArray sortedArrayUsingComparator:^NSComparisonResult(Events *obj1, Events *obj2) {
Events *time1 = obj1;
Events *time2 = obj2;
if (time1 > time2) {
return (NSComparisonResult)NSOrderedDescending;
}
else if (time1 < time2) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
[self.tableView reloadData];
}
}
});
}];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[searchEventsTask resume];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
isFiltered = NO;
}
else {
isFiltered = YES;
}
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[c] %#",searchText];
self.filteredEventsArray = [eventNamesArray filteredArrayUsingPredicate:pred];
[self.tableView reloadData];
}
//- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
// [resign fi]
//}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (isFiltered == YES) {
return filteredEventsArray.count;
}
else {
return self.eventNamesArray.count;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *eventsWithFirstLetter;
if (isFiltered == YES) {
NSString *firstLetter = [self.filteredEventsArray objectAtIndex:section];
eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
else {
NSString *firstLetter = [self.eventNamesArray objectAtIndex:section];
eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"eventTitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Events *event;
if (isFiltered == YES) {
NSString *firstLetter = [self.filteredEventsArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
}
else {
NSString *firstLetter = [self.eventNamesArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *firstLetter = [self.eventNamesArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
DescriptionViewController *descriptionViewController = (DescriptionViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"descriptionController"];
descriptionViewController.eventNameDesc = event.eventDescription;
descriptionViewController.navigationItem.title = event.eventName;
[self.navigationController pushViewController:descriptionViewController animated:YES];
}
#end
If I read this correctly, you only store one letter in the eventNamesArray: NSString *eventsAsStrings = [event.eventName substringToIndex:1];.
So the predicate self.filteredEventsArray = [eventNamesArray filteredArrayUsingPredicate:pred]; will only match, if you type one letter.
So one simple solution would be to store the complete event names in their own array, so that you can match against those.
Okay I have three UITableViews that I need to all originate from the same viewcontroller code. I need to populate them all from the .m file of AG_ViewController.
AG_ViewController.h
#import <UIKit/UIKit.h>
#interface AG_ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>{
IBOutlet UITableView *yesterdayTableView;
IBOutlet UITableView *tomorrowTableView;
IBOutlet UITableView *tableView;
IBOutlet UILabel *todaysDate;
IBOutlet UILabel *subtractDate;
IBOutlet UILabel *addDate;
}
#end
AG_ViewController.m
#import "AG_ViewController.h"
#import "AG_Storage.h"
#import "AG_AddItemViewController.h"
#interface AG_ViewController ()
#property NSMutableArray *mainArray;
#property NSMutableArray *yesterdayArray;
#property NSMutableArray *tomorrowArray;
#property NSDate *todayDate;
#property NSDate *tomorrowsDate;
#property NSDate *yesterdaysDate;
#property int counter;
#property(weak,nonatomic)IBOutlet UIButton *yesterdayButton;
#property(weak,nonatomic)IBOutlet UIButton *tomorrowButton;
#property(weak,nonatomic)IBOutlet UIButton *backButton;
#end
#implementation AG_ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.mainArray = [[NSMutableArray alloc] init];
self.yesterdayArray = [[NSMutableArray alloc]init];
self.tomorrowArray = [[NSMutableArray alloc]init];
[self loadInitialData];
}
- (void)loadInitialData
{
// Do any additional setup after loading the view, typically from a nib.
//NSDate Info
NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *today = [[NSDate alloc]init];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMMM dd, yyyy"];
self.todayDate = today;
self.tomorrowsDate = [today dateByAddingTimeInterval: secondsPerDay];
self.yesterdaysDate = [today dateByAddingTimeInterval: -secondsPerDay];
NSString *todayString = [dateFormat stringFromDate:self.todayDate];
NSString *tomorrowString = [dateFormat stringFromDate:self.tomorrowsDate];
NSString *yesterdayString = [dateFormat stringFromDate:self.yesterdaysDate];
todaysDate.text = todayString;
addDate.text = tomorrowString;
subtractDate.text = yesterdayString;
AG_Storage *theDateToday = [[AG_Storage alloc]init];
theDateToday.todaysDate = self.todayDate;
//Populate mainArray
for (int x= 0; x!=-99; x++) {
//get ready to call the NSUserDefaults
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"%#%d",todayString,x]];
AG_Storage *someStorageObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
AG_Storage *storeToArray = [[AG_Storage alloc]init];
storeToArray.itemName = someStorageObject;
if (someStorageObject != nil) {
//add the data to the mainArray and update counter
[self.mainArray addObject:storeToArray];
self.counter++;
}
else if ((someStorageObject == nil) && (x==99)){
//exit when done
x=-100;
}
}
//Populate yesterdayArray
for (int x= 0; x!=-99; x++) {
//get ready to call the NSUserDefaults
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"%#%d",yesterdayString,x]];
AG_Storage *someStorageObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
AG_Storage *storeToArray = [[AG_Storage alloc]init];
storeToArray.itemName = someStorageObject;
if (someStorageObject != nil) {
//add the data to the mainArray and update counter
[self.yesterdayArray addObject:storeToArray];
self.counter++;
}
else if ((someStorageObject == nil) && (x==99)){
//exit when done
x=-100;
}
}
//Populate tomorrowArray
for (int x= 0; x!=-99; x++) {
//get ready to call the NSUserDefaults
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"%#%d",tomorrowString,x]];
AG_Storage *someStorageObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
AG_Storage *storeToArray = [[AG_Storage alloc]init];
storeToArray.itemName = someStorageObject;
if (someStorageObject != nil) {
//add the data to the mainArray and update counter
[self.tomorrowArray addObject:storeToArray];
self.counter++;
}
else if ((someStorageObject == nil) && (x==99)){
//exit when done
x=-100;
}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(tableView == tomorrowTableView){
return [self.tomorrowArray count];
}
else if(tableView == yesterdayTableView)
return [self.yesterdayArray count];
else
return [self.mainArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableViewer cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableViewer dequeueReusableCellWithIdentifier:#"thisCell"];
AG_Storage *toDoItem = [self.mainArray objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemName;
if (toDoItem.completed) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (IBAction)unwindToList:(UIStoryboardSegue *)segue
{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMMM dd, yyyy"];
AG_AddItemViewController *source = [segue sourceViewController];
AG_Storage *item = source.store;
NSDate *dateCreated = item.creationDate;
NSString *todayString = [dateFormat stringFromDate:self.todayDate];
NSString *dateCreatedString = [dateFormat stringFromDate:dateCreated];
NSString *tomorrowString = [dateFormat stringFromDate:self.tomorrowsDate];
NSString *yesterdayString = [dateFormat stringFromDate:self.yesterdaysDate];
//Set up file storage!
if (item != nil) {
if ([dateCreatedString isEqualToString:todayString]) {
[self.mainArray addObject:item];
[tableView reloadData];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:item.itemName];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:[NSString stringWithFormat:#"%#%d",todayString,self.counter]];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else if ([dateCreatedString isEqualToString:tomorrowString]){
[self.tomorrowArray addObject:item];
[tableView reloadData];
NSLog(#"THIS WORKED TOO :D");
}
else if ([dateCreatedString isEqualToString:yesterdayString]){
[self.yesterdayArray addObject:item];
[tableView reloadData];
NSLog(#"THIS WORKED");
}
else{
}
}
self.counter++;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableViewer didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableViewer deselectRowAtIndexPath:indexPath animated:NO];
AG_Storage *tappedItem = [self.mainArray objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
[tableViewer reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableViews commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMMM dd, yyyy"];
NSString *todayString = [dateFormat stringFromDate:self.todayDate];
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Delete from storage
for (int x = 0; x!=-99; x++) {
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"%#%d",todayString,x]];
AG_Storage *someStorageObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
AG_Storage *storeToArray = [[AG_Storage alloc]init];
storeToArray.itemName = someStorageObject;
AG_Storage *toDoItem = [self.mainArray objectAtIndex:indexPath.row];
NSString *compare = toDoItem.itemName;
//If they equal then delete from NSUserDefaults
if ([compare isEqualToString:someStorageObject]) {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:[NSString stringWithFormat:#"%#%d",todayString,x]];
[[NSUserDefaults standardUserDefaults]synchronize];
x=-100;
}
else
{
}
if (x>10) {
x=-100;
}
}
[self.mainArray removeObjectAtIndex:indexPath.row];
[tableViews deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
#end
I've only ever set up one table at a time, so how do I make yesterdayTableView become populated by yesterdayArray for instance?
You can keep one tableView around.
Steps for,One tableView multiple cell as per your need
1) Design seperate cell for yesterday and tomorrow nibs/storyboard
2) swap cell on click of some button tableView:cellForRowAtIndexPath via if else conditions.
or else go for viewController containment
Several ways to do so,
If you only need to display one tableView at a time you could do something like this in your tableView:cellForRowAtIndexPath: data source method:
The stupid way
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (kAppState_Yesterday) { // Set the controllerstate so that it knows that the arrayDatasource should be yesterday
// create and return cell corresponding to yesterdayArray.
}
}
If all your cells look the same, you could have a NSArray *dataSource and just assign it to the different arrays.
The "a bit smarter way"
if userClicksButton `display yesterday array`
self.dataSource = self.yesterdayArray
end
In this way, your tableView:cellForRowAtIndexPath: will be more consistent since if won't be full of conditionals.
If things get more complicated, I would recommend to use Controller Containment.
I've retrieved data from 2 different shared Google Calendars, and stored the data in an array. I need to sort the data into a sectioned UITableView, sorted by date.
Heres my code:
CalendarModel.h
#import "JSONModel.h"
#import "Time.h"
#interface CalendarModel : JSONModel
#property (strong, nonatomic) NSString* title;
#property (strong, nonatomic) NSArray<Time>* time;
#end
CalendarModel.m
#import "CalendarModel.h"
#implementation CalendarModel
+(JSONKeyMapper*)keyMapper
{
return [[JSONKeyMapper alloc] initWithDictionary:#{
#"gd$when": #"time",
#"title.$t": #"title",
}];
}
#end
Time.h
#import "JSONModel.h"
#protocol Time #end
#interface Time : JSONModel
#property (strong, nonatomic) NSString* startTime;
#property (strong, nonatomic) NSString* endTime;
#end
Time.m does nothing, as it's handled by JSONModel
SportsViewController.m
#import "SportsViewController.h"
#import "JSONModelLib.h"
#import "CalendarModel.h"
#import "Time.h"
#import "JSONValueTransformer.h"
#interface SportsViewController ()
#property (strong, nonatomic) NSMutableArray *events;
#property (strong, nonatomic) NSArray *music;
- (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate;
- (NSDate *)dateByAddingYears:(NSInteger)numberOfYears toDate:(NSDate *)inputDate;
#end
#implementation SportsViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//make HTTP call
NSString* searchCall = [NSString stringWithFormat:#"http://www.google.com/calendar/feeds/kao1d80fd2u5kh7268caop11o4%%40group.calendar.google.com/public/full?alt=json"];
NSString* searchCall2 = [NSString stringWithFormat:#"http://www.google.com/calendar/feeds/3qag5m8iad46mtvsnnqbtrcjjg%%40group.calendar.google.com/public/full?alt=json"];
[JSONHTTPClient getJSONFromURLWithString: searchCall
completion:^(NSDictionary *json, JSONModelError *err) {
//got JSON back
NSLog(#"Got Sports JSON from web: %#", json);
if (err) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:[err localizedDescription]
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles: nil] show];
return;
}
//initialize the models
_events = [CalendarModel arrayOfModelsFromDictionaries:
json[#"feed"][#"entry"]
];
if (_events) NSLog(#"Loaded successfully sports models");
//show the Events
[_events addObjectsFromArray:_music];
NSLog(#"%#", _events);
[self.tableView reloadData];
}];
[JSONHTTPClient getJSONFromURLWithString: searchCall2
completion:^(NSDictionary *json2, JSONModelError *err2) {
//got JSON back
NSLog(#"Got Music JSON from web: %#", json2);
if (err2) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:[err2 localizedDescription]
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles: nil] show];
return;
}
//initialize the models
_music = [CalendarModel arrayOfModelsFromDictionaries:
json2[#"feed"][#"entry"]
];
if (_music) NSLog(#"Loaded successfully music models");
[_events addObjectsFromArray:_music];
//show the Events
[self.tableView reloadData];
}];
//[events addObjectsFromArray:music];
[self.tableView reloadData];
}
;
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - table methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _events.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CalendarModel* event = _events[indexPath.row];
NSString *dato = [[event.time objectAtIndex:0] startTime];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
NSDate *gmtDate = [formatter dateFromString: dato];
formatter.dateFormat = #"dd-MM-yyyy HH:mm";
dato = [formatter stringFromDate:gmtDate];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SportCell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%#",
event.title
];
cell.detailTextLabel.text = dato;
return cell;
}
#end
So basically all the data i need sorted resides in the _events array. I just do not get how i sort it by date into sections. The reason why startTime and endTime are NSStrings is that, that's what i am returned by the call to the shared calendar on Google
First group all your events - you'll have to take care of variable scoping (I'm using days and groupedEvents locally but you'll have to declare those as ivars/properties)
NSMutableArray *days = [NSMutableArray array];
NSMutableDictionary *groupedEvents = [NSMutableDictionary dictionary];
- (void)groupEventsIntoDays
{
for (CalendarModel *event in _events)
{
NSString *dato = [[event.time objectAtIndex:0] startTime];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
NSDate *gmtDate = [formatter dateFromString: dato];
if (![days containsObject:gmtDate])
{
[days addObject:gmtDate];
[groupedEvents setObject:[NSMutableArray arrayWithObject:event] forKey:gmtDate];
}
else
{
[((NSMutableArray*)[groupedEvents objectForKey:gmtDate]) addObject:event];
}
}
days = [[days sortedArrayUsingSelector:#selector(compare:)] mutableCopy];
}
Section headers:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width, 30)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:header.bounds];
[header addSubview:headerLabel];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"dd-MM-yyyy HH:mm";
NSString *dateAsString = [formatter stringFromDate:[days objectAtIndex:section]];
[headerLabel setText:dateAsString];
return header;
}
I only touched the first two lines in your cellForRow - you can modify the rest as needed for display/formatting:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDate *date = [days objectAtIndex:indexPath.section];
CalendarModel *event = [((NSMutableArray*)[groupedEvents objectForKey:date]) objectAtIndex:indexPath.row];
NSString *dato = [[event.time objectAtIndex:0] startTime];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
NSDate *gmtDate = [formatter dateFromString: dato];
formatter.dateFormat = #"dd-MM-yyyy HH:mm";
dato = [formatter stringFromDate:gmtDate];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SportCell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%#",
event.title
];
cell.detailTextLabel.text = dato;
return cell;
}
Using this tutorial, I made an iPhone blog app. It uses the count of the array created to setup the number of rows. I don't want to do every single item, because there are over 200 right now and growing. When I return any number for rows in section, it always crashes with the error about 0 beyond bounds of empty array. What else do I need to tweak from this tutorial to only allow the first 20 items to show in tableview?
UPDATE: I think I am making some progress. In the reqeustFinished method where it sorts the array, I edited it to make it this:
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[entries removeLastObject];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
NSLog(#"%#", entries);
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
Adding the line to removeLastObject for entries, removed the first item (which is ideally the ONLY one I would want on the first day). Are there other methods that would allow me to remove a range of objects at Index?
Here is the code I have for the Table View Class and DataSources.
- (void)refresh {
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feeds = [NSArray arrayWithObjects:#"addressofxmlfile",
nil];
for (NSString *feed in _feeds) {
NSURL *url = [NSURL URLWithString:feed];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[_queue addOperation:request];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(refreshInvoked:forState:) forControlEvents:UIControlEventValueChanged];
[self refresh];
}
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
// Refresh table here...
[_allEntries removeAllObjects];
[self.tableView reloadData];
[self refresh];
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = [item valueForChild:#"guid"];
NSString *articleDateString = [item valueForChild:#"pubdate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSString *articleImage = [item valueForChild:#"description"];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateofarticle = [dateFormatter stringFromDate:articleDate];
NSString *days = [articleImage substringFromIndex:7];
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate
articleImage:articleImage
date:thedate] autorelease];
[entries addObject:entry];
}
}
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
}else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
- (void)requestFinished:(ASIHTTPRequest *)request {
[_queue addOperationWithBlock:^{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil) {
NSLog(#"Failed to parse %#", request.url);
} else {
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
}
}];
}
}];
[self.refreshControl endRefreshing];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"Error: %#", error);
[self refresh];
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// [tableView setBackgroundColor:[UIColor redColor]];
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_allEntries count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
CALayer * l = [cell.imageView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:11];
[l setBorderWidth:2.0];
[l setBorderColor:[[UIColor blackColor] CGColor]];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
UIFont *cellFont = [UIFont fontWithName:#"Papyrus" size:19];
UIFont *cellFont2 = [UIFont fontWithName:#"Papyrus" size:17];
// cell.imageView.image = [UIImage imageNamed:#"icon#2x.png"];
cell.textLabel.text = entry.date;
cell.detailTextLabel.text = entry.articleTitle;
cell.detailTextLabel.textColor = [UIColor blackColor];
cell.textLabel.font = cellFont;
cell.detailTextLabel.font = cellFont2;
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 73.4;
}
You are assigning allEntries to new Array in the Refresh method here:
- (void)refresh {
self.allEntries = [NSMutableArray array];
The tutorial only does this in the ViewDidLoad Method. Not sure if this is a problem as i don't know exactly when/how refresh is called.
Found this answer that shows how to hide cells/rows here.