I am getting an error which I don't understand because I have declared the property/ies. Have commented out the error in the AllListViewController.m file in the cellForRowAtIndexPath: method.
Here are the files:
Checklist.h
#import <Foundation/Foundation.h>
#interface Checklist : NSObject <NSCoding>
#property (nonatomic, copy) NSString *name;
#property (nonatomic, strong) NSMutableArray *items;
#property (nonatomic, copy) NSString *iconName;
-(int)countUncheckedItems;
#end
Checklist.m
#import "Checklist.h"
#import "ChecklistItem.h"
#implementation Checklist
-(id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super init])) {
self.name = [aDecoder decodeObjectForKey:#"Name"];
self.items = [aDecoder decodeObjectForKey:#"Items"];
self.iconName = [aDecoder decodeObjectForKey:#"IconName"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:#"Name"];
[aCoder encodeObject:self.items forKey:#"Items"];
[aCoder encodeObject:self.iconName forKey:#"IconName"];
}
-(id)init
{
if ((self = [super init])) {
self.items = [[NSMutableArray alloc] initWithCapacity:20];
self.iconName = #"Appointments";
}
return self;
}
-(int)countUncheckedItems
{
int count = 0;
for (ChecklistItem *item in self.items) {
if (!item.checked) {
count += 1;
}
}
return count;
}
-(NSComparisonResult)compare:(Checklist *)otherChecklist
{
return [self.name localizedStandardCompare:otherChecklist.name];
}
#end
AllListsViewController.h
#import <UIKit/UIKit.h>
#import "ListDetailViewController.h"
#class DataModel;
#interface AllListsViewController : UITableViewController <ListDetailViewControllerDelegate, UINavigationControllerDelegate>
#property (nonatomic, strong) DataModel *dataModel;
#end
AllListsViewController.m
#import "AllListsViewController.h"
#import "Checklist.h"
#import "ChecklistViewController.h"
#import "ChecklistItem.h"
#import "DataModel.h"
#interface AllListsViewController ()
#end
#implementation AllListsViewController
- (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;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.dataModel setIndexOfSelectedChecklist:indexPath.row];
Checklist *checklist = self.dataModel.lists[indexPath.row];
[self performSegueWithIdentifier:#"ShowChecklist" sender:checklist];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowChecklist"]) {
ChecklistViewController *controller = segue.destinationViewController;
controller.checklist = sender;
}
else if ([segue.identifier isEqualToString:#"AddChecklist"]) {
UINavigationController *navigationController = segue.destinationViewController;
ListDetailViewController *controller = (ListDetailViewController *)navigationController.topViewController;
controller.delegate = self;
controller.checklistToEdit = nil;
}
}
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:#"ListNavigationController"];
ListDetailViewController *controller = (ListDetailViewController *)navigationController.topViewController;
controller.delegate = self;
Checklist *checklist = self.dataModel.lists[indexPath.row];
controller.checklistToEdit = checklist;
[self presentViewController:navigationController animated:YES completion:nil];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.dataModel.lists count];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.dataModel.lists removeObjectAtIndex:indexPath.row];
NSArray *indexPaths = #[indexPath];
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
cell.imageView.image = [UIImage imageNamed:Checklist.iconName]; /* Use of undeclared identifier; did you mean 'Checklist'? or Property 'iconName' not found on object of type 'Checklist'*/
return cell;
}
Checklist *checklist = self.dataModel.lists[indexPath.row];
cell.textLabel.text = checklist.name;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%d Remaining", [checklist countUncheckedItems]];
int count = [checklist countUncheckedItems];
if ([checklist.items count] == 0) {
cell.detailTextLabel.text = #"(No Items)";
} else if (count == 0) {
cell.detailTextLabel.text = #"All Done";
} else {
cell.detailTextLabel.text = [NSString stringWithFormat:#"%d Remaining", count];
}
return cell;
}
/*
// 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.
}
*/
-(void)listDetailViewControllerDidCancel:(ListDetailViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)listDetailViewController:(ListDetailViewController *)controller didFinishAddingChecklist:(Checklist *)checklist
{
[self.dataModel.lists addObject:checklist];
[self.dataModel sortChecklists];
[self.tableView reloadData];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)listDetailViewController:(ListDetailViewController *)controller didFinishEditingChecklist:(Checklist *)checklist
{
[self.dataModel sortChecklists];
[self.tableView reloadData];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if(viewController == self) {
[self.dataModel setIndexOfSelectedChecklist:-1];
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.delegate = self;
NSInteger index = [self.dataModel indexOfSelectedChecklist];
if(index >= 0 && index < [self.dataModel.lists count]) {
Checklist *checklist = self.dataModel.lists[index];
[self performSegueWithIdentifier:#"ShowChecklist" sender:checklist];
}
}
#end
You have not declared the variable "Checklist" & trying to access the "iconName". Actually you are trying to access it directly via class name.
I can see you have created an instance if "Checklist" few lines down. So better create that instance before using Checklist.iconName
May be in the beginning of function after CellIdentifier creation.
Checklist *checklist = self.dataModel.lists[indexPath.row];
cell.imageView.image = [UIImage imageNamed:checklist.iconName]; /* Use of undeclared identifier; did you mean 'Checklist'? or Property 'iconName' not found on object of type 'Checklist'*/
return cell;
}
As per your code, "Checklist" is your class name, whereas the instance starts with small "c" as "checklist". So you also might have got confused.
Hope that helps.
Related
I am getting this error and my search function does nothing when the user starts typing a query( XCODE 5.1).
I dont know how the -webView is related to this error as I have not used webView in these files. Any advice would be appreciated. Thank you.
OrdersViewController.h
#import <UIKit/UIKit.h>
#interface OrdersViewController : UITableViewController <UISearchBarDelegate>
//NSmurray is set because we want to edit/move items as well (this will be implemented later)
#property (nonatomic, strong) NSMutableArray *jsonParseArray;
#property (nonatomic, strong) NSMutableArray *ordersArray;
#property (strong, nonatomic) IBOutlet UISearchBar *searchOrders;
#property (nonatomic, strong ) NSMutableArray *orderSearchResults;
#pragma mark -
#pragma mark Class Methods
-(void) retrieveOrderData;
#end
OrdersViewController.m
#import "OrdersViewController.h"
#import "Order.h"
#import "OrderDetailViewController.h"
#define getDataURL #"http://gkhns-macbook-pro.local/gj-3.php"
#interface OrdersViewController ()
#end
#implementation OrdersViewController
#synthesize jsonParseArray, ordersArray;
- (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;
//
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.title = #"ORDERS";
[self retrieveOrderData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)searchThroughOrders {
self.orderSearchResults = nil;
//gettig the text that is entered in the search bar and it creates nspredicated self containes the search and this text will be replaced by search field
NSPredicate *orderResultsPredicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searchOrders.text];
//filtering the predicate that is set before
self.orderSearchResults = [[self.ordersArray filteredArrayUsingPredicate:orderResultsPredicate] mutableCopy];
}
//detect when the user typed in the search
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self searchThroughOrders];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//are we in regular table view or search display view? Lets check that
if (tableView == self.tableView)
{
return ordersArray.count;
}
else{
[self searchThroughOrders];
// Return the number of rows in the section.
return self.orderSearchResults.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"OrderCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle=UITableViewCellStyleDefault;
}
if (tableView== self.tableView)
// Configure the cell...
{Order *orderObject;
orderObject = [ordersArray objectAtIndex:indexPath.row];
cell.textLabel.text=orderObject.order_id;
cell.detailTextLabel.text=orderObject.firstname;
}
else
{
cell.textLabel.text = self.orderSearchResults [indexPath.row];
}
//accessory
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
/*
// 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.
if ([[segue identifier] isEqualToString:#"pushOrderDetailView"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Order* object = [ordersArray objectAtIndex:indexPath.row];
[[segue destinationViewController] getOrder:object];
}
}
#pragma mark -
#pragma mark Class Methods
-(void) retrieveOrderData{
NSURL * url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];
jsonParseArray=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//orders array
ordersArray= [[NSMutableArray alloc]init];
//loop through the jason array
for (int i=0; i<jsonParseArray.count; i++)
{
//create the order object
NSString *oId = [[jsonParseArray objectAtIndex:i] objectForKey:#"order_id"];
NSString *eMail = [[jsonParseArray objectAtIndex:i] objectForKey:#"email"];
NSString *fName = [[jsonParseArray objectAtIndex:i] objectForKey:#"firstname"];
NSString *lName = [[jsonParseArray objectAtIndex:i] objectForKey:#"lastname"];
NSString *sName = [[jsonParseArray objectAtIndex:i] objectForKey:#"store_name"];
NSString *iPrefix = [[jsonParseArray objectAtIndex:i] objectForKey:#"invoice_prefix"];
NSString *pAddress1 = [[jsonParseArray objectAtIndex:i] objectForKey:#"payment_address_1"];
NSString *sPaymentAddress2 = [[jsonParseArray objectAtIndex:i] objectForKey:#"payment_address_2"];
//add order to orders array
[ordersArray addObject:[[Order alloc]initWithOrderId: (NSString *)oId andInvoicePrefix: (NSString*)iPrefix andStoreName:(NSString*)sName andFirstName:(NSString*)fName andLastName:(NSString*)lName andEmail:(NSString*)eMail andPaymentAddress1:(NSString*)pAddress1 andPaymentAddress2:(NSString*)sPaymentAddress2]];
}
//reload the view
[self.tableView reloadData];
}
#end
I was using searchbar only instead of search bar and the search display controller which may have caused this issue.
Also done a few changes to the searchdisplay controller implementation below which fixed the issue.
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self searchThroughOrders:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
-(void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView{
[tableView registerClass:[CustomOrdersCell class] forCellReuseIdentifier:#"OrderCell"];
}
-(void)searchThroughOrders:(NSString *)searchText scope:(NSString*)scope {
//getting the text that is entered in the search bar and it creates nspredicated self containes the search and this text will be replaced by search field
NSPredicate *orderResultsPredicate = [NSPredicate predicateWithFormat:#"order_id contains[c] %#", searchText];
//filtering the predicate that is set before
_orderSearchResults = [ordersArray filteredArrayUsingPredicate:orderResultsPredicate];
}
Maybe there's someone outthere who can help me fiure out my problem. I cant seem to display the playlistItems using cocoalibspotify. I have set up my playlistview and the first ableviewcontroller shows the playlist but when i try to call the items of the selected playlist I seem to get 0 numbersof row as my outputs show. the first view show how i pass the indexpath to the secondviewcontroller. the second script show my .h and .m files of the playlistitemsTavle view controller.
Overview.m - tableView with Playlists
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[playlistView deselectRowAtIndexPath:indexPath animated:NO];
playlistItemViewController *trailsController = [[playlistItemViewController alloc] initWithStyle:UITableViewStylePlain];
trailsController.currentPlaylist = [playlistArray objectAtIndex:indexPath.row];
//[[self navigationController] pushViewController:trailsController animated:YES];
[self getSongs];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showPlaylistItem"]) {
UITableViewCell *BasicCell = (UITableViewCell *) sender;
NSIndexPath *ip = [self.tableView indexPathForCell:BasicCell];
SPPlaylist *selectedPlaylist = [playlistArray objectAtIndex:ip.row];
playlistItemViewController *pivc = (playlistItemViewController *) segue.destinationViewController;
pivc.currentPlaylist = selectedPlaylist;
}
}
playlistitemsViewController.h -
#import <UIKit/UIKit.h>
#import "CocoaLibSpotify.h"
#import "Simple_PlayerAppDelegate.h"
#import "overViewController.h"
#interface playlistItemViewController : UITableViewController
{
UITableView *tableView;
}
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (strong, readwrite, nonatomic) SPPlaylist *currentPlaylist;
#end
playlistViewController.m - this should call the playlist items
#import "playlistItemViewController.h"
#interface playlistItemViewController ()
#end
#implementation playlistItemViewController {
}
#synthesize currentPlaylist;
#synthesize tableView;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"numberOfRowsInSection: %d",[[currentPlaylist items] count]);
return [[currentPlaylist items] count];
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SubtitleCell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [[[currentPlaylist items] objectAtIndex:indexPath.row] valueForKey:#"name"];
return cell;
if (indexPath.row == 0) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SubtitleCell"];
[[cell.backgroundView superview] bringSubviewToFront:cell.backgroundView];
cell.textLabel.text = #"";
}
else{
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"SubtitleCell"];
}
SPPlaylistItem * item = [[currentPlaylist items] objectAtIndex:[[currentPlaylist items]count] - indexPath.row];
cell.textLabel.text = [item.item name];
if (item.itemClass == [SPTrack class]) {
SPTrack * track = item.item;
cell.detailTextLabel.text = [track consolidatedArtists];
}
}
return cell;
}
#end
You need to wait for the playlist to load before the items are available.
Your playlist view controller needs to use SPAsyncLoading to load the playlist, something list this:
[SPAsyncLoading waitUntilLoaded:self.currentPlaylist timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedItems, NSArray *notloadedItems) {
[self.tableView reloadData];
}];
Playlist loading can take a while, so make sure you put up some "loading" UI. You'll also need to load the visible tracks in a similar manner before their names will be available.
I've been writing an app that has custom protocol to send the data from the child view to parent view the classes is
MainViewController
AddViewController (child to mainviewcontroller)
DaysViewController (child to addviewcontroller)
the custom protocol was declared in DaysViewController and implemented in AddViewController
AddViewController.h
#import <UIKit/UIKit.h>
#import "DaysViewController.h"
#import "Course.h"
#import "Student.h"
#interface AddViewController : UITableViewController<UIActionSheetDelegate,UIPickerViewDelegate,UIPickerViewDataSource,UIPickerViewAccessibilityDelegate,UITextFieldDelegate,DaysViewControllerDelegate>
{
NSArray *hoursarray;
UIActionSheet *aac;
IBOutlet UITextField *NameTx,*HoursTx,*DaysTx,*TimeTx;
Student *st;
Course *cc;
}
-(void) pickerDoneClick;
-(IBAction)fillTheOtherData;
#property (nonatomic ,strong) UIActionSheet *aac;
#end
AddViewController.m
#import "AddViewController.h"
#interface AddViewController ()
#end
#implementation AddViewController
#synthesize aac;
- (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;
//viewP.frame = CGRectMake(0, 154, 320, 205);
hoursarray = [[NSArray alloc]initWithObjects:#"2",#"3",#"4", nil];
[self.tableView setScrollEnabled:NO];
[DaysTx setEnabled:NO];
[TimeTx setEnabled:NO];
[HoursTx setKeyboardType:UIKeyboardTypeDecimalPad];
cc = [[Course alloc]init];
//UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapped:)];
//[self.view addGestureRecognizer:tapgr];
}
-(void)tapped:(UITapGestureRecognizer *)tap
{
[self.view endEditing:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [hoursarray count];
}
//-(IBAction)addCourse
//{
// [UIView beginAnimations:#"view" context:nil];
// [UIView setAnimationDuration:1];
// viewP.frame = CGRectMake(0, 500, 320, 205);
// [UIView commitAnimations];
//
//}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [hoursarray objectAtIndex:row];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 3)
{
aac = [[UIActionSheet alloc]initWithTitle:#"How many ?" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
UIPickerView *picker = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 44, 0, 0)];
picker.delegate = self;
picker.dataSource = self;
UIToolbar *pickerToolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[pickerToolBar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc]init];
UIBarButtonItem *flexspace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexspace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDoneClick)];
[barItems addObject:doneBtn];
[pickerToolBar setItems:barItems animated:YES];
[aac addSubview:pickerToolBar];
[aac addSubview:picker];
[aac showInView:self.view];
[aac setBounds:CGRectMake(0, 0, 320, 464)];
}
else if (indexPath.row == 2)
{
DaysViewController *days = [self.storyboard instantiateViewControllerWithIdentifier:#"Days"];
days.delegate = self;
[self.navigationController pushViewController:days animated:YES];
}
}
-(void) pickerDoneClick
{
[aac dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)chooseDays:(DaysViewController *)controller withArray:(NSArray *)theDaysArray
{
NSLog(#"I'm # chooseDays method");
NSLog(#"Before the add !!");
NSLog(#"chooseDays Method and the array is %#",theDaysArray);
cc.days = [NSMutableArray arrayWithObject:theDaysArray];
NSLog(#"After the add");
NSLog(#"chooseDays Method and the array is %#",cc.days);
// [self dismissViewControllerAnimated:YES completion:nil];
}
-(void)cancelChooseDays:(DaysViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)fillTheOtherData
{
cc.name = NameTx.text;
cc.hour = [HoursTx.text integerValue];
NSLog(#"The name is %# and the hour credit is %d",cc.name,cc.hour);
}
#end
DaysViewController.h
#import <UIKit/UIKit.h>
#import "Course.h"
#class DaysViewController;
#protocol DaysViewControllerDelegate <NSObject>
#required
-(void)chooseDays:(DaysViewController *)controller withArray:(NSArray *)theDaysArray;
-(void)cancelChooseDays:(DaysViewController *)controller;
#end
#interface DaysViewController : UITableViewController
{
Course *courseDays;
NSArray *days;
NSMutableArray *dayChosen;
}
#property (nonatomic,weak) id<DaysViewControllerDelegate> delegate;
-(IBAction)done:(id)sender;
-(IBAction)cancel:(id)sender;
#end
DaysViewController.m
#import "DaysViewController.h"
#interface DaysViewController ()
#end
#implementation DaysViewController
#synthesize delegate;
- (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;
days = [[NSArray alloc]initWithObjects:#"Saturday",#"Sunday",#"Monday",#"Teusday",#"Wednesday",#"Thursday",#"Friday", nil];
dayChosen = [[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [days count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DaysCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DaysCell"];
}
cell.textLabel.text = [days objectAtIndex:indexPath.row];
return cell;
}
-(IBAction)done:(id)sender
{
//Course *course = [[Course alloc]init];
//[course.days addObject:dayChosen];
//NSArray *daysArray = [NSArray arrayWithObject:dayChosen];
NSLog(#"The Days are %#",dayChosen);
[self.delegate chooseDays:self withArray:dayChosen];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)cancel:(id)sender
{
[self.delegate cancelChooseDays:self];
}
/*
// 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 - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[dayChosen addObject:[days objectAtIndex:indexPath.row]];
NSLog(#"Days are %#",dayChosen);
}
#end
MainViewController has a button that take me to AddViewController and AddViewController has same button that takes me to DaysViewController , all the views has a UITableView .
what I want to do is when I send the data from DaysViewController to AddViewController to put it in an array and dismiss the view AddViewController should show up but instead MainViewController shows and this is what I dont want it to be.
AddViewController and DaysViewController have a UINavigationController but MainViewController doesn't.
Thank you in advance.
Okay, I think I know what your problem is. In your cancel function, try and switch this line of code:
[self dismissViewControllerAnimated:YES completion:nil];
With this line of code:
[self.navigationController popViewControllerAnimated:YES];
Let me know if that helps.
Have added a method and protocol to pass the addItemViewController:didFinishEditingItem method to the main view controller (ChecklistsViewController) after completing a text edit. (The edit command and segue are invoked by pressing a disclosure detail button on the Checklists main page.)
Problem is that after completing the edit and pressing the "Done" button, no completed text edit gets passed back to the original Checklists page, which means that the original edit was was not passed over. I have had no compiling warning messages.
Can you tell me what's wrong and why no completed edit is getting passed back to Checklists? Thanks in advance.
AddItemViewController.h
import
#class AddItemViewController;
#class ChecklistItem;
#protocol AddItemViewControllerDelegate <NSObject>
- (void)addItemViewControllerDidCancel:(AddItemViewController *)controller;
- (void)addItemViewController:(AddItemViewController *)controller didFinishAddingItem:(ChecklistItem *)item;
- (void)addItemViewController:(AddItemViewController *)controller didFinishEditingItem:(ChecklistItem *)item;
#end
#interface AddItemViewController : UITableViewController <UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UITextField *textField;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *doneBarButton;
#property (nonatomic, weak) id <AddItemViewControllerDelegate> delegate;
#property (nonatomic, strong) ChecklistItem *itemToEdit;
- (IBAction)cancel;
- (IBAction)done;
#end
AddItemViewController.m
#import "AddItemViewController.h"
#import "ChecklistItem.h"
#interface AddItemViewController ()
#end
#implementation AddItemViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if(self.itemToEdit != nil) {
self.title = #"Edit Item";
self.textField.text = self.itemToEdit.text;
self.doneBarButton.enabled = YES;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (IBAction)cancel
{
[self.delegate addItemViewControllerDidCancel:self];
}
- (IBAction)done
{
if(self.itemToEdit == nil) {
ChecklistItem *item = [[ChecklistItem alloc] init];
item.text = self.textField.text;
item.checked = NO;
[self.delegate addItemViewController:self didFinishAddingItem:item];
} else {
self.itemToEdit.text = self.textField.text;
[self.delegate addItemViewController:self didFinishEditingItem:self.itemToEdit];
}
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
return nil;
}
- (void)viewDidUnload {
[self setTextField:nil];
[self setDoneBarButton:nil];
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.textField becomeFirstResponder];
}
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newText = [theTextField.text stringByReplacingCharactersInRange:range withString:string];
self.doneBarButton.enabled = ([newText length] > 0);
return YES;
}
#end
ChecklistsViewController.h
#import <UIKit/UIKit.h>
#import "AddItemViewController.h"
#interface ChecklistsViewController : UITableViewController <AddItemViewControllerDelegate>
#end
ChecklistsViewController.m
#import "ChecklistsViewController.h"
#import "ChecklistItem.h"
#interface ChecklistsViewController ()
#end
#implementation ChecklistsViewController {
NSMutableArray *items;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
items = [[NSMutableArray alloc] initWithCapacity:20];
ChecklistItem *item;
item = [[ChecklistItem alloc]init];
item.text = #"Walk the dog";
item.checked = NO;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Brush my teeth";
item.checked = YES;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Learn iOS development";
item.checked = YES;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Soccer practice";
item.checked = NO;
[items addObject:item];
item = [[ChecklistItem alloc]init];
item.text = #"Eat ice cream";
item.checked = YES;
[items addObject:item];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [items count];
}
- (void)configureCheckmarkForCell:(UITableViewCell *)cell withChecklistItem:(ChecklistItem *)item
{
UILabel *label = (UILabel *)[cell viewWithTag:1001];
if(item.checked) {
label.text =#"√";
} else {
label.text = #"";
}
}
- (void)configureTextForCell:(UITableViewCell *)cell withChecklistItem:(ChecklistItem *)item
{
UILabel *label = (UILabel *)[cell viewWithTag:1000];
label.text = item.text;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ChecklistItem"];
ChecklistItem *item = [items objectAtIndex:indexPath.row];
[self configureTextForCell:cell withChecklistItem:item];
[self configureCheckmarkForCell:cell withChecklistItem:item];
return cell;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
ChecklistItem *item = [items objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"EditItem" sender:item];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
ChecklistItem *item = [items objectAtIndex:indexPath.row];
[item toggleChecked];
[self configureCheckmarkForCell:cell withChecklistItem:item];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[items removeObjectAtIndex:indexPath.row];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (void)addItemViewControllerDidCancel:(AddItemViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)addItemViewController:(AddItemViewController *)controller didFinishAddingItem:(ChecklistItem *)item
{
int newRowIndex = [items count];
[items addObject:item];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)addItemViewController:(AddItemViewController *)controller didFinishEditingItem:(ChecklistItem *)item
{
int index = [items indexOfObject:item];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCheckmarkForCell:cell withChecklistItem:item];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"AddItem"]) {
UINavigationController *navigationController = segue.destinationViewController;
AddItemViewController *controller = (AddItemViewController *)navigationController.topViewController;
controller.delegate = self;
} else if ([segue.identifier isEqualToString:#"EditItem"]) {
UINavigationController *navigationController = segue.destinationViewController;
AddItemViewController *controller = (AddItemViewController *)navigationController.topViewController;
controller.delegate = self;
controller.itemToEdit = sender;
}
}
#end
I am trying to add Search to Todo demo application. I have below code so far with Search working. The issue with below code is that the Pagination doesn't work anymore. There is simlilar question about pagination but when "number of rows in section + 1" returned, the app crashes with [__NSArrayM objectAtIndex:] error. How do I get the Pagination working?
// MyTableController.h
#import <Parse/Parse.h>
#interface MyTableController : PFQueryTableViewController
#end
// MyTableController.m
#import "MyTableController.h"
#interface MyTableController() <UISearchDisplayDelegate> {
}
#property (nonatomic, strong) UISearchBar *searchBar;
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic, strong) NSMutableArray *searchResults;
#end
#implementation MyTableController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
self.className = #"Todo";
self.keyToDisplay = #"text";
self.pullToRefreshEnabled = YES;
self.paginationEnabled = YES;
self.objectsPerPage = 5;
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
self.tableView.tableHeaderView = self.searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar
contentsController:self];
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
self.searchController.delegate = self;
CGPoint offset = CGPointMake(0, self.searchBar.frame.size.height);
self.tableView.contentOffset = offset;
self.searchResults = [NSMutableArray array];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)filterResults:(NSString *)searchTerm {
[self.searchResults removeAllObjects];
PFQuery *query = [PFQuery queryWithClassName: self.className];
[query whereKey:#"text" containsString:searchTerm];
NSArray *results = [query findObjects];
[self.searchResults addObjectsFromArray:results];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterResults:searchString];
return YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.tableView) {
return self.objects.count;
} else {
return self.searchResults.count ;
}
}
#pragma mark - Parse
- (void)objectsDidLoad:(NSError *)error {
[super objectsDidLoad:error];
}
- (void)objectsWillLoad {
[super objectsWillLoad];
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.className];
if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query orderByAscending:#"priority"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [object objectForKey:#"text"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Priority: %#", [object objectForKey:#"priority"]];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
#end
In your own implementation of numberOfRowsInSection you must return numberOfRows + 1. But then you must write your code considering you have more cells than query returning. Check out your heightForRowAtIndexPath and others methods: there can be calls to [self.objects objectAtIndex:self.objects.count]. I mean, if indexPath.row == self.objects.count, its a "Load More" cell.
If you overriding willSelectRowAtIndexPath or didSelectRowAtIndexPath, you must do this in the top of method
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
or add this (previous case is prefered)
if (indexPath.row == self.objects.count)
{
[self loadNextPage];
}
Customization of Load More cell placed in -(PFTableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath
And im using
-(PFTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath
instead of
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: