Unable to implement UIPopoverController delegation - iphone

I have the following view controller in my UIPopover:
#protocol StorePopoverDelegate
- (void)storeSelected:(NSString *)store;
#end
#interface StorePopoverViewController : UITableViewController
{
NSMutableArray* items;
}
#property (nonatomic, assign) id<StorePopoverDelegate> delegate;
#end
When an item is selected I want my delegate to get called:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (delegate != nil) {
[delegate storeSelected:[items objectAtIndex:indexPath.row]];
}
}
The delegate class that handles storeSelected is implemented:
-(IBAction)storesButtonClicked:(id)sender
{
storesPopoverViewController = [[StorePopoverViewController alloc] initWithStyle:UITableViewStylePlain];
storePopover.delegate = (id)self;
storePopover = [[UIPopoverController alloc] initWithContentViewController:storesPopoverViewController];
[storePopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
#pragma Store Popover Delegate Methods
- (void)storeSelected:(NSString *)store;
{
NSLog(#"%# was clicked", store);
[storePopover dismissPopoverAnimated:YES];
}
In my - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath the delegate is nil. I'm not sure why? I am assigning it.

In your storesButtonClicked: method you are setting the delegate of the storePopover (which is not even initialized at that point). You should be setting the delegate property of storePopoverViewController instead.
storePopoverViewController.delegate = (id)self;

Related

Setting a NSString to the sending end of a segue

I made a simple project to explain my problem. Basically what I did was make a project with the templet of a Master Detail Application. Then in the
DetailViewController.h
nothing
DetailViewController.m
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"showDetail"])
{
[segue.destinationViewController setCellName2:#"New String"];
}
}
MasterViewController.h
#property(nonatomic,strong) NSString *cellName2;
MasterViewController.m
#synthesize cellName2;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(#"%#", cellName2);
}
My problem is in the detailViewController where I set the cellName2, I cant set it because the detailViewController is the receivingViewController of the segue. Is their a method to set the sendingViewController end of a segue?
Edit
After Firo's answer my code looks like this now
MasterViewContoller.h
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#interface MasterViewController : UITableViewController <DetailViewDelegate>
#property(nonatomic,strong) NSString *cellName2;
#end
.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
#synthesize cellName2;
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
self.cellName2 = cellName;
NSLog(#"%#", self.cellName2);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSDate *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[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;
}
*/
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"showDetail"]) {
/* assigning self as delegate, telling the detail view that I implement
* setCellName2:, so it (the detailVC) can call it whenever it wants to.
*/
[segue.destinationViewController setDelegate:self];
}
}
// my implementation of the DetailViewDelegate protocol that I abide to
/* note: #pragma mark is not required, just for comment, documentation
* and find-ability purposes
*/
//#pragma mark - DetailViewDelegate
// note: this is just a property setter so this is not actually needed
//- (void)setCellName2:(NSString *)cellName {
// self.cellName2 = cellName;
// NSLog(#"%#", self.cellName2);
//}
#end
DetailViewContoller.h
#import <UIKit/UIKit.h>
/* defining a protocol, whoever is a DetailViewDelegate must implement my
* defined methods
*/
#protocol DetailViewDelegate <NSObject>
- (void)setCellName2:(NSString *)cellName;
#end
#interface DetailViewController : UIViewController
/* storing a delegate property. Whoever sets themselves to my delegate
* must implement my DetailViewDelegate's methods (setCellName2: in this case)
*/
#property (weak, nonatomic) id<DetailViewDelegate> delegate;
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
.m
#import "DetailViewController.h"
#interface DetailViewController ()
- (void)configureView;
#end
#implementation DetailViewController
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//[self.delegate setCellName2:#""];
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"showDetaila"])
{
[segue.destinationViewController setCellName2:#"New String"];
}
}
#end
The problem now is, i am getting the error "Use of undeclared identifier 'cellName'; did you mean 'cellName2'?"
You are looking for delegates and protocols. Since you are not segueing from your detailVC to your masterVC you cannot put this setter in prepareForSegue. You need to store a reference to the master and have callbacks to it. Here is how you would do it with your basic example:
DetailViewController.h
/* defining a protocol, whoever is a DetailViewDelegate must implement my
* defined methods
*/
#protocol DetailViewDelegate <NSObject>
- (void)setCellName2:(NSString *)cellName;
#end
#interface DetailViewController : UIViewController
/* storing a delegate property. Whoever sets themselves to my delegate
* must implement my DetailViewDelegate's methods (setCellName2: in this case)
*/
#property (weak, nonatomic) id<DetailViewDelegate> delegate;
#end
DetailViewController.m
#implementation DetailViewController
// some action or method
- (IBAction)buttonPress:(id)sender {
// look below at Master's prepareForSegue
/* calling the method that my delegate implements, my delegate can be any
* object that implements my protocol (DetailViewDelegate)
*/
[self.delegate setCellName2:#""];
}
#end
MasterViewController.h
#import "DetailViewController.h"
// saying I implement the DetailViewDelegate protocol (and all necessary methods)
#interface MastViewController : UITableViewController <DetailViewDelegate>
#end
MasterViewController.m
#interface MasterViewController ()
#property(strong, nonatomic) NSString *cellName2;
#end
#implementation MasterViewController
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"showDetail"]) {
/* assigning self as delegate, telling the detail view that I implement
* setCellName2:, so it (the detailVC) can call it whenever it wants to.
*/
[segue.destinationViewController setDelegate:self];
}
}
// my implementation of the DetailViewDelegate protocol that I abide to
/* note: #pragma mark is not required, just for comment, documentation
* and find-ability purposes
*/
#pragma mark - DetailViewDelegate
// note: this is just a property setter so this is not actually needed
- (void)setCellName2:(NSString *)cellName {
_cellName = cellName
NSLog("%#", self.cellName);
}
#end
I would give you some more information about delegates and protocols but it is an extremely common pattern when dealing with iOS development. You also should become extremely familiar with delegates and protocols, you will find it useful in many situations and it will help you better understand iOS development and make you a more competent programmer. If something does not work (or make sense) let me know. I just typed this up in SO so there could be some mild mistakes.
Edit
Note: If this becomes to far from the original question you may need to just create a new one.
Your main issue here is that you have self.cellName2 = cellName; in your MasterViewController. According to your original post you want the DetailVC to set this, right? So it will need to go into DetailViewController's viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
[self.delegate setCellName2:#"My custom text!"];
}
Then remove:
self.cellName2 = cellName;
NSLog(#"%#", self.cellName2);
From your MasterViewController's viewDidLoad. Your error is with the first line there (I am assuming). What is cellName? It is not a string and you have not defined it as a variable or property, hence the error.
Are you sure that the code is in the right class? And that you have the segues hooked up correctly in the storyboard?
In your DetailViewController code, you indicate that the segue identifier is "showDetail". It would seem to me that you ought to be handling that in your MasterViewController, as the pattern is typically that MasterViewController is responsible for seguing to the DetailViewController for the purpose of showing details.
Basically, if the destinationViewController property of the segue is NOT an instance of MasterViewController, then either the segue is not correctly configured or your code is in the wrong place.
If I'm mistaken please post more code.

sending data from DetailViewController to MasterViewController

This is what exactly I'm trying to do.
wizardviewcontroller.m
- (IBAction)onCountryClick:(id)sender {
MJDetailViewController *detailViewController = [[MJDetailViewController alloc] initWithNibName:#"MJDetailViewController" bundle:nil];
[self presentPopupViewController:detailViewController animationType:MJPopupViewAnimationSlideLeftRight];
}
User click country button a popup shows with list.
when user select a row button title should change.
This is my detailview,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
WizardViewController *mj = [[WizardViewController alloc] initWithNibName:#"WizardViewController" bundle:nil];
mj.countryselected = [countryNames objectAtIndex:indexPath.row];
[mj.countryButton setTitle:mj.countryselected forState:UIControlStateNormal];
[self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationFade];
}
DetailViewController is dismissing, but countryButtonTitle is not updating. I know this is because the wizardview is not refreshing. I would like to know the correct workaround in this case.
Hope this helps to get better answer.
Make Protocol in MJDetailViewController
#protocol MJDetailViewControllerDelegate;
#interface MJDetailViewController : UIViewController
#property (nonatomic,assign) id< MJDetailViewControllerDelegate> delegate;
#end
#protocol MJDetailViewControllerDelegate <NSObject>
- (void)selectedContry:(NSString *)title;
#end
And call like
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
NSString *title = [countryNames objectAtIndex:indexPath.row];
if ([self.delegate respondsToSelector:#selector(selectedContry:)]) {
[self.delegate selectedContry:title];
}
[self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationFade];
}
Add MJDetailViewControllerDelegate as a protocol in WizardViewController.h)
Now implement selectedContry: method in WizardViewController.m like:
- (void)selectedContry:(NSString *)title
{
[self.countryButton setTitle:title forState:UIControlStateNormal];
}
Hope it helps you.

Master Detail Application - Static Table in Detail View

I'm trying to code an app in Xcode 4, with storyboarding. It's a master detail application, and it all worked fine, with the table and the detail view. But in my detail view, I would like to have a static table to display the data. In a grouped table style way, with the "key" on the left and "value" on the right, if that's a way to put it... So, it's all working fine until I put a table into my UIView. Apparently you have to put it in a UITableView for it to work, so I deleted the UIView that Xcode made for me and put in a UITableView in its place. I set it up EXACTLY the same (I think) with the identifier, title etc... and then connect the table cells up with outlets and what not. But now when I enter the view, I just get an empty table (well, not empty, just all the rows say "Detail" in rather than the actual data I want). I don't see why! D: I even changed DetailViewController.h to say "UITableViewController" as well! No avail... :( Could someone please enlighten me as to what I'm doing wrong! I bet it's really simple... :L Here's my code
MasterViewController.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface MasterViewController : UITableViewController
#property (strong, nonatomic) DetailViewController *detailViewController;
#property (strong) NSMutableArray *verbs;
#end
MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "VerbData.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
#synthesize verbs = _verbs;
- (void)awakeFromNib
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
}
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.detailViewController = (DetailViewController *) [[self.splitViewController.viewControllers lastObject] topViewController];
self.title = #"Verbs";
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _verbs.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"VerbCell"];
VerbData *verb = [self.verbs objectAtIndex:indexPath.row];
cell.textLabel.text = verb.infinitive;
cell.detailTextLabel.text = verb.english;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[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;
}
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
VerbData *object = [self.verbs objectAtIndex:indexPath.row];
self.detailViewController.detailItem = object;
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
VerbData *object = [self.verbs objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#import "VerbData.h"
#interface DetailViewController : UITableViewController <UISplitViewControllerDelegate>
#property (strong, nonatomic) VerbData *detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (weak, nonatomic) IBOutlet UILabel *jeOutlet;
#property (weak, nonatomic) IBOutlet UILabel *tuOutlet;
#property (weak, nonatomic) IBOutlet UILabel *ilOutlet;
#property (weak, nonatomic) IBOutlet UILabel *nousOutlet;
#property (weak, nonatomic) IBOutlet UILabel *vousOutlet;
#property (weak, nonatomic) IBOutlet UILabel *ilsOutlet;
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
#end
#implementation DetailViewController
#pragma mark - Managing the detail item
#synthesize detailItem = _detailItem;
#synthesize jeOutlet = _jeOutlet;
#synthesize tuOutlet = _tuOutlet;
#synthesize ilOutlet = _ilOutlet;
#synthesize nousOutlet = _nousOutlet;
#synthesize vousOutlet = _vousOutlet;
#synthesize ilsOutlet = _ilsOutlet;
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.masterPopoverController != nil) {
[self.masterPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = self.detailItem.english;
self.jeOutlet.text = self.detailItem.je;
self.tuOutlet.text = self.detailItem.tu;
self.ilOutlet.text = self.detailItem.il;
self.nousOutlet.text = self.detailItem.nous;
self.vousOutlet.text = self.detailItem.vous;
self.ilsOutlet.text = self.detailItem.ils;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = self.detailItem.infinitive;
[self configureView];
}
- (void)viewDidUnload
{
[self setJeOutlet:nil];
[self setTuOutlet:nil];
[self setIlOutlet:nil];
[self setNousOutlet:nil];
[self setVousOutlet:nil];
[self setIlsOutlet:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#pragma mark - Split view
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
barButtonItem.title = NSLocalizedString(#"Master", #"Master");
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
self.masterPopoverController = popoverController;
}
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
// Called when the view is shown again in the split view, invalidating the button and popover controller.
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
self.masterPopoverController = nil;
}
#end
First thing I will try to debug is -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method. Is it return values? Try to put NSLog in this method and check it.
Or maybe this will help you:
Note: If you want to change the background color of a cell (by setting the background color of a cell via the backgroundColor property declared by UIView) you must do it in the tableView:willDisplayCell:forRowAtIndexPath: method of the delegate and not in tableView:cellForRowAtIndexPath: of the data source. Changes to the background colors of cells in a group-style table view has an effect in iOS 3.0 that is different than previous versions of the operating system. It now affects the area inside the rounded rectangle instead of the area outside of it.
The code must handle the case where dequeueReusableCellWithIdentifier answers nil...
static NSString *CellIdentifier = #"VerbCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

Why is my tableView not displaying objects?

First of I would like to start with I am 100% new to iPhone development. I believe this is a quite simple question for someone experienced. Anyhow, what I am trying to do is:
The user should via the SearchUI be able to search for objects from my database. If the object exist, display it in the tableView where the search-objects will be displayed. I manage to get the objects from the database but not instance them into the tableview and display them.
Honestly I don't know what I am doing wrong. All help will be really appreciated and also some explaining if possible. Under method - (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects - I try to move the objects into the tableView without any success. You find the method in FirstViewController.m at the end of pragma mark TableView Data Scource methods. Here is my code:
FirstViewController.h class
#import <UIKit/UIKit.h>
#import <RestKit/RestKit.h>
#interface FirstViewController : UIViewController <UITableViewDataSource, RKObjectLoaderDelegate>
{
UISearchDisplayController *searchDisplayController;
UISearchDisplayController *searchBar;
UITableView *table;
NSArray *allItems;
NSArray *searchResults;
}
#property (nonatomic, retain) IBOutlet UISearchDisplayController *searchDisplayController;
#property (nonatomic, retain) IBOutlet UISearchDisplayController *searchBar;
#property (nonatomic, retain) IBOutlet UITableView *table;
#property (nonatomic, copy) NSArray *allItems;
#property (nonatomic, copy) NSArray *searchResults;
#end
FirstViewController.m class
#import "FirstViewController.h"
#import "Task.h"
interface FirstViewController ()
end
implementation FirstViewController
#synthesize searchDisplayController;
#synthesize searchBar;
#synthesize allItems;
#synthesize searchResults;
#synthesize table;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
//self.listContent = [[NSArray alloc] initWithObjects:#"John", #"Paul", nil];
//self.filteredListContent = [NSMutableArray arrayWithCapacity:10];
[super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
else
{
return YES;
}
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
return NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
return NO;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)pSearchBar
{
[[RKObjectManager sharedManager].mappingProvider setMapping:[Task getMapping] forKeyPath:#"tasks"];
NSString *path = [NSString stringWithFormat:#"%#/%#/%#", #"/book/1/tasks/", pSearchBar.text, #".json"];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:path delegate:self];
NSLog(#"Search: %#", pSearchBar.text);
}
#pragma mark - TableView Data Scource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.searchResults count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
return cell;
}
- (void) deselect {
//[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
// Respond to user selection tap by coloring the navigation bar
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath
{
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
self.searchResults = objects;
[self.table reloadData];
for(Task *task in objects)
{
if ([task isKindOfClass:[Task class]])
{
NSLog(#"Loaded Book ID: %# ; Name: %# ; Book: %#", task.id, task.name, task.book.name);
}
}
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error
{
NSLog(#"Encountered an error: %#", error);
}
#end
Step1. Since your TableView is an IBOutlet, check you tableView datasource and delegate mappings in the .xib file for this view controller. My doubt is that the hooking is not correct.
Step2. If the hook ups in .xib file are correct, then you should do
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
self.searchResults = objects;
NSLog(#"%#", searchResults)
[self.table reloadData];
....
}
and check if the NSLog is logging the searchResults array. If that's empty for some reason, your numberOfRowsInSection delegate method will return 0 and hence your tableView will be empty.
Hope this helps.
in the first line
#interface FirstViewController : UIViewController <UITableViewDataSource, RKObjectLoaderDelegate>
{
UISearchDisplayController *searchDisplayController;
UISearchDisplayController *searchBar;
UITableView *table;
NSArray *allItems;
NSArray *searchResults;
}
replace this line with below code
#interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, RKObjectLoaderDelegate>
{
UISearchDisplayController *searchDisplayController;
UISearchDisplayController *searchBar;
IBOutlet UITableView *table;
NSArray *allItems;
NSArray *searchResults;
}
and connect the tableview delegate and tableview datasource in interface builder.
Hope it helps.

how to send data backword from second class to first class in iphone

i am try to exchange the one cell to the value of other cell but my value is not transfer proper bec my value is passing second class to first class but not string value is passing array reference why what is the mistake in my code can u help me
for this i create delegate method
this is my originstart.h file
import
#import "RegexKitLiteDemoAppDelegate.h"
#class airport;
#protocol OriginstartDelegate <NSObject>
#required
- (void)Originstart:(NSString *)Origin forIndexPath:(NSIndexPath *)indexPath;
#end
#interface Originstart : UITableViewController {
RegexKitLiteDemoAppDelegate *app;
airport *selectedAirport;
}
#property(nonatomic,retain)NSString*name;
#property(nonatomic,retain)airport *selectedAirport;
#property (nonatomic, copy) NSIndexPath *indexPathToChange;
#property (nonatomic, assign) id<OriginstartDelegate> delegate;
#end
this is my orginestart.m file
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return app.lstAirports.count;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
airport* a=(airport*)[app.lstAirports objectAtIndex:indexPath.row];
NSLog(#"str:%#",a);
cell.textLabel.text =a.Name;
cell.detailTextLabel.text=a.Code;
// Configure the cell...
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *newStation = [[app.lstAirports objectAtIndex:indexPath.row]description];
[delegate Originstart:newStation forIndexPath:self.indexPathToChange];
[self.navigationController popViewControllerAnimated:YES];
}
this is my Tfirst.m file
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"accessory selected");
if ([indexPath section] == 0)
{
// load the appropriate view for the accessory selected
if ([indexPath row] == 0)
{
Originstart *viewtwo = [[Originstart alloc] initWithStyle:UITableViewStyleGrouped];
viewtwo.indexPathToChange = indexPath;
viewtwo.delegate = self;
[self.navigationController pushViewController:viewtwo animated:YES];
[viewtwo release];
}
else{
NSLog(#"accessory right");
}
}
}
#pragma mark - Delegate protocol method
- (void)Originstart:(NSString *)Origin forIndexPath:(NSIndexPath *)indexPath {
[datasource replaceObjectAtIndex:indexPath.row withObject:Origin];
[self.tableView reloadData];
}
this is my airport.h file where i create two string variable and one array for take value and display for in originstart classwith name and code i writen this in here in class
originstart.m airport* a=(airport*)[app.lstAirports objectAtIndex:indexPath.row];
NSLog(#"str:%#",a);
cell.textLabel.text =a.Name;
cell.detailTextLabel.text=a.Code;
and final this class arport class
//
// airport.h
// RegexKitLiteDemo
//
// Created by pradeep.yadav on 9/13/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface airport : NSObject {
NSString *Code;
NSString *Name;
NSArray *DestinationAirports;
}
#property(nonatomic,retain)NSString *Code;
#property(nonatomic,retain)NSString *Name;
#property(nonatomic,retain)NSArray *DestinationAirports;
#end
To achieve what u want , just try these steps:
1.First, create a property of first class in the second class.
2.In the first class create those variables or objects as properties to which u want to pass the data from the second class.
3.(Hope u are using navigation controller based app ) While pushing from the first to second view controller u create a instance of the second class and pass it pushViewController method. Add the following line of code along with it.....
secondViewObj.firstView=self;
where secondViewObj is the instance of the secondViewController class and firstView is the property declared in that second class.
4.Now in the second class when u want to pass the data to first class just add the following line of code:
firstView.dataMember1=value;
where dataMember1 is the variable or object which was created as a property as mentioned in the 2nd point. Hope this helps.
In the FirstViewController class where u push to SecondviewController have the following piece of code:
SecondViewController *svc = [SecondViewController alloc]init];
svc.vc = self;
[self.navigationController pushViewController:svc animated:YES];
and also have a property declared for the data u want to pass to the firstView Controller.
In this case it s going to be a integer variable.
#property (nonatomic) int selectedValue and also synthesize it.
Now in the secondViewController , declare a property for the firstViewController like this
#property (nonatomic, retain) FirstViewController *vc; and synthesize it.
Where u want to pass the data to the FirstViewController have the following code,
vc.selectedValue = 1;
Now after popping back to the firstViewController , if u chk the value of the selectedValue variable u will find the value has been passed from second to first.
Hope this helps..
The simplest apprroach is to set an object in FirstViewController here is the way
SecondViewController
FirstViewController *instanceOfFirstView;
#property (nonatomic, retain) FirstViewController *instanceOfFirstView;
#synthesize instanceOfFirstView;
[instanceOfFirstView setValueNeedTobeBroughtFromSecondView:#"VAlue set"]
FirstViewController
NSString *valueNeedTobeBroughtFromSecondView;
#property (nonatomic, retain) NSString *valueNeedTobeBroughtFromSecondView;
#synthesize valueNeedTobeBroughtFromSecondView;
SecondViewController *aSecondViewController=[[SecondViewController alloc] init];
[aSecondViewController setInstanceOfFirstView: self];