My program not going inside the delegate method - ios

I am trying to use a delegate method in AddCity.m controller that I created in the City.m controller. The method is
City.m
- (void)EditCityController:(id)controller didEditItem:(id)item
{
if(item)
{
NSDictionary *d = (NSDictionary *)item;
[self.model addNewCity:[d valueForKey:#"cityName"] forProvince:self.ro inMayor:[d valueForKey:#"mayorName"] inPopulation:[[d valueForKey:#"population"]intValue] inYearEstablished:[[d valueForKey:#"yearEstablished"]intValue]];
[self.model saveChanges];
}
// Dismiss the modal view controller
[controller dismissViewControllerAnimated:YES completion:nil];
}
City.h
#interface Cities :
UITableViewController<NSFetchedResultsControllerDelegate, EditCityDelegate>
And then in AddCity.h i have
#protocol EditCityDelegate;
#interface AddCity : UIViewController<UITextFieldDelegate>
#property (nonatomic, assign) id <EditCityDelegate> delegate;
#protocol EditCityDelegate <NSObject>
- (void) EditCityController:(id)controller didEditItem:(id)item;
#end
I am calling it from AddCity.m (Currently trying to the cancel button).
- (IBAction)cancel:(id)sender {
[self.delegate EditCityController:self didEditItem:nil];
}
When i put a breakpoint what happens is that it hits the self.delegate line but it does not go into the EditCityController method in the City.m controller.Any idea on what i am doing wrong?

I assume you call AddCity.m in City.m and present it using presentViewController
AddCity *addcityVC = [AddCity new];
addcityVC.delegate = self; // initialize the delegate here
[self presentViewController:addCityVC animated:YES completion:nil];
You need to initialize the delegate back to self so it can call the method you need
Hope this helps

Related

iOS self.delegate is nil even after being set

I have a controller that gets instantiated and pushed onto the navigation controller like this -
In ParentVC.m
ThingContainerViewController *thingContainer = [[ThingContainerViewController alloc] init];
thingContainer.delegate = self;
[self.navigationController pushViewController:thingContainer animated:YES];
Now I want to send back a value to ParentVC when the thingContainer is closed. So I have implemented a delegate as follows:
in ParentVC.h
#interface ParentVC : UIViewController <..., ThingContainerViewControllerDelegate>
in ThingContainer.h
#protocol ThingContainerViewControllerDelegate <NSObject>
- (void)addItemViewController:(id)controller didFinishEnteringItem:(NSInteger)page;
#end
....
#interface
....
#property (nonatomic, weak) id <ThingContainerViewControllerDelegate> delegate;
....
#end
in ParentVC.m
- (void)addItemViewController:(id)controller didFinishEnteringItem:(NSInteger)page {
self.page = page;
}
in ThingContainer.m
- (IBOutlet) ... closeButtonWasTapped:(UIButton *)button {
NSLog(#"%ld", (long)indexOfPage);
[self.delegate addItemViewController:self didFinishEnteringItem:indexOfPage];
[[self navigationController] popViewControllerAnimated: YES];
}
At this point, self.delegate is null, so the method in the ParentVC never gets called. Any idea how I can fix it?

Delegate method does not get called - iOS

AddBillViewController.h:
#protocol AddBillDelegate <NSObject>
- (void)addBillViewControllerDidAddOneBill;
#end
#interface AddBillViewController : UIViewController
#property (retain, nonatomic)id <AddBillDelegate> delegate;
#end
AddBillViewController.m:
- (IBAction)AddBill:(id)sender {
[self.delegate addBillViewControllerDidAddOneBill];
[self dismissViewControllerAnimated:YES completion:nil];
}
HomeViewController.m:
#interface HomeViewController () <AddBillDelegate>
#property (strong, nonatomic)AddBillViewController *abVC;
#end
#implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.abVC = [[AddBillViewController alloc] init];
self.abVC.delegate = self;
}
- (void)addBillViewControllerDidAddOneBill {
NSLog(#"Added a bill.");
}
#end
As you can see, there is button in AddBillViewController, when the button is pressed, addBill method will be called, then the delegate method addBillViewControllerDidAddOneBill in HomeViewController should be called, however in fact, it doesn't.
I think you are not getting the reference right here in this line
self.abVC = [[AddBillViewController alloc] init];
If you are performing a segue, like the AddBillViewController is your next controller, set delegate in performSegue: function
like
AddBillViewController *vc = [segue destinationViewController];
[vc setDelegate:self];

Moving to and fro modal view inside TabBarController

hi i am working on an app and all was going good till now.... i am stuck at this point..
here is my storyboard snapshot..
in the DemoTableViewController when i clock on "filters" button .. Brands TableViewController is opened modally .
after user select multiple rows in Brands TableViewController ,, he then clicks on done button and view controller is dismissed by this code:
-(IBAction)DonePressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
I am storing the user selections in NSMutableSet and it is to be Used in DemoTableViewController so that i can reload the table rows according to the selection but i dont know how to send NSMutableSet to DemoTableViewController and then reload the table according to selection..
what is the right way to dismiss modal view and reload the parent DemoTableViewController
i know i am not doing it correctly but can anyone help me in doing it...
here is some code ---
DemoTVC.h
#import <UIKit/UIKit.h>
#import "MyModelClass.h"
#import "brandsTableViewController.h"
#interface demoTableViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate,MyModelProtocol,FilterProtocol>
#property (strong, nonatomic) IBOutlet UITableView *demoTable;
- (IBAction)FilterPressed:(id)sender;
#end
DemoTVC.m--
the method which performs segue--
- (IBAction)FilterPressed:(id)sender {
[self performSegueWithIdentifier:#"FilterPressed" sender:self];
}
the delegate method which is called to get the values from BrandsTVC--
-(void)GetTheSet:(NSMutableSet *)MySet{
[self dismissViewControllerAnimated:YES completion:nil];
}
viewdidLoad--
- (void)viewDidLoad
{
[super viewDidLoad];
productArray = [[NSMutableArray alloc] init];
homeModel = [[MyModelClass alloc] init];
// Set this view controller object as the delegate for the home model object
homeModel.delegate = self;
// Call the download items method of the home model object
[homeModel downloadItemswithurl:#"url is written here"];
}
BrandsTVC.h---
#import <UIKit/UIKit.h>
#import "MyModelClass.h"
#protocol FilterProtocol <NSObject>
-(void)GetTheSet:(NSMutableSet *) MySet;
#end
#interface brandsTableViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate,MyModelProtocol>
#property (strong, nonatomic) IBOutlet UITableView *RetailerList;
#property (strong,nonatomic) NSMutableSet *selectStates;
#property (nonatomic, weak) id<FilterProtocol> delegate;
- (IBAction) DonePressed:(id)sender;
#end
BrandsTVC.m---
#interface brandsTableViewController ()
{
MyModelClass *myModelClass;
NSMutableArray *BrandsArray;
brandsTableViewController *Delegate;
}
#end
viewDidLoad----
- (void)viewDidLoad
{
[super viewDidLoad];
BrandsArray = [[NSMutableArray alloc] init];
self.selectStates=[NSMutableSet new];
myModelClass = [[MyModelClass alloc] init];
// Set this view controller object as the delegate for the home model object
myModelClass.delegate = self;
// Call the download items method of the home model object
[myModelClass downloadItemswithurl:#"url to get json"];
self.tableView.allowsMultipleSelection = YES;
}
Done Button is called ---
- (IBAction)DonePressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
id<FilterProtocol> strongDelegate = self.delegate;
if ([strongDelegate respondsToSelector:#selector(GetTheSet:)]) {
[strongDelegate GetTheSet:self.selectStates];
}
}
#end
You can keep those elements in NSUserDefaults, and whenever DemoTableViewController appears, you send [tableView reloadData]. Do this in the viewDidAppear: method.
You can also use Core Data, but there are a lot of details to explain how to do that.
After a lot of trial and error i come to know that in BrandsTVC--
- (IBAction)DonePressed:(id)sender {
NSLog(#"done pressed %#",self.delegate);
[delegate GetTheSet:self.selectStates];
}
self.delegate is giving me NULL.
delegate is not setup and i cant figure out how to do that.. someone help me..
this answer solved my problem :D
custom viewcontroller delegate not working

Obj-C Delegate inside Delegate

I have subclassed a view that I am using as header view it has some buttons delegate inside it and it works perfect .
However I am presenting a modalViewController above my viewController .
(in my modalViewController I have implemented the same header , and it does get the delegates from the header) but this view it self has to delegate to the previous viewController if the back button of the header is pressed.
I have made the same functions but my viewController never gets it's delegate... :(
I am quite new to Obj-C and I don't know maybe I am doing something illegal here.
here is the code of modalViewController trying to delegate to the previous viewController
#pragma mark - header delegate
- (void)header:(header *)header backbuttonPressed:(UIButton *)sender
{
if(header == logo)
{
NSLog(#"gotBackButtonDelegate");
//delete the items array
//_itemSourceArray = nil;
[delegate allEventsDrillPage:self backbuttonPressed:sender];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
This delegate does triggers from the header view.
however in my previous viewController:
- (void)allEventsDrillPage:(allEventsDrillPage *)allEventsDrillPage backbuttonPressed:(UIButton *)sender //doesn't work :(
{
NSLog(#"got back delegate!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// [self dismissViewControllerAnimated:YES completion:nil];
_drillPage = nil;
}
never get called
I calling the modalViewController like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[_allEventsTableView deselectRowAtIndexPath:indexPath animated:YES];
[self->_allEventsTableView setNeedsDisplay];
[self->_allEventsTableView reloadData];
_drillPage = [[allEventsDrillPage alloc]initWithDictionary:((NSDictionary*) [_tableDataSource objectAtIndex:indexPath.row])];
_drillPage.delegate = self;
[self presentViewController:_drillPage animated:YES completion:nil];
}
in its .h file I did
#interface allEvents : UIViewController <headerDelegate , UITableViewDataSource , UITableViewDelegate ,allEventsDrillPageDelegate>
I don't get what am I missing here :-/ can some1 take a look please ?
if needed more info I will added just ask for it.
EDIT:
protocol of delegate inside the modalViewController
#class allEventsDrillPage;
#protocol allEventsDrillPageDelegate //define delegate protocol
- (void)allEventsDrillPage:(allEventsDrillPage*)allEventsDrillPage backbuttonPressed:(UIButton*)sender;
#end
#interface allEventsDrillPage : UIViewController
{
id<allEventsDrillPageDelegate> __weak delegate;
....
}
#property (weak, nonatomic) id <allEventsDrillPageDelegate> delegate; //define
Let's try:
- (void)header:(header *)header backbuttonPressed:(UIButton *)sender
{
if(header == logo)
{
NSLog(#"gotBackButtonDelegate");
// delete the items array
//_itemSourceArray = nil;
// my comment: you should replace "delegate" to "_delegate"
// and it works. I tested. It's OK. Wow.
[_delegate allEventsDrillPage:self backbuttonPressed:sender];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
nmh's answer is correct. I wrote up an answer earlier but his came in faster, so I thought I would take out the other parts and just add the explanations here.
You have this:
#interface allEventsDrillPage : UIViewController
{
id<allEventsDrillPageDelegate> __weak delegate;
....
}
#property (weak, nonatomic) id <allEventsDrillPageDelegate> delegate;
With this id<allEventsDrillPageDelegate> __weak delegate; you declare an ivar.
With this #property (weak, nonatomic) id <allEventsDrillPageDelegate> delegate; you are declaring a property.
Since Xcode 4.4 you get auto-synthesization.
And so this line:
_drillPage.delegate = self;
You are setting the one via the property.
And not this:
id<allEventsDrillPageDelegate> __weak delegate;
So what you have here:
[delegate allEventsDrillPage:self backbuttonPressed:sender];
You are using the ivar above, not the one via the property.
And delegate is thus nil.
And so, if you try to send a message to the delegate using nmh's solution or:
[self.delegate allEventsDrillPage:self backbuttonPressed:sender];
It should work as expected.
Addendum to dismissing modal view controller:
Instead of dismissing it from the current view controller, dismiss it from the one who presented it, so:
- (void)header:(header *)header backbuttonPressed:(UIButton *)sender
{
if(header == logo)
{
NSLog(#"gotBackButtonDelegate");
[_delegate allEventsDrillPage:self backbuttonPressed:sender];
//or self.delegate
}
}
And in:
- (void)allEventsDrillPage:(allEventsDrillPage *)allEventsDrillPage backbuttonPressed:(UIButton *)sender
{
NSLog(#"got back delegate!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
[self dismissViewControllerAnimated:YES completion:nil];
_drillPage = nil;
}
Or even better:
- (void)allEventsDrillPage:(allEventsDrillPage *)allEventsDrillPage backbuttonPressed:(UIButton *)sender
{
NSLog(#"got back delegate!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
[self dismissViewControllerAnimated:YES completion:^{
_drillPage = nil;
}];
}
Hope this helps.

delegate = nil, transfer information between VCs issue

I just started to learn obj-c and I have question about delegates. I know that on SOF is a lot of similar threads, but I was looking for and really didn't get my issue (maybe cause I'm beginner). Here's my problem: I want to use my own delegate and transfer an information from SlaveClass to MainClass. In SlaveClass in buttonDidClick: action, I declare delegate which is equal to NIL. Even I don't know where I should start to looking for mistake. Thanks in advance for any type of advice. Here's my code which refer to delegate:
SlaveClass.h
#protocol slaveDelegate <NSObject>
-(void)transferNameDidClick:(NSString *)text;
#end
// --------------------------------------------------------------------------------
#interface SlaveClass : UIViewController
#property (nonatomic, strong) id <slaveDelegate> myOwnDelegate;
#end
SlaveClass.m (here appears NIL)
-(void)buttonDidClick:(id)sender
{
if ([_myOwnDelegate respondsToSelector:#selector(transferNameDidClick:)])
{
[_myOwnDelegate transferNameDidClick:(_textField.text)];
}
}
MainClass.h
#interface MainClass : UIViewController <slaveDelegate>
#end
MainClass.m
-(void)transferNameDidClick:(NSString *)text
{
SlaveClass *delegate = [[SlaveClass alloc] init];
[delegate setMyOwnDelegate:self];
[_label setText:text];
NSLog(#"text: %#",text);
}
You are setting your delegate in wrong place. You have to set the delegate before going to slaveClass
mainClass.m
Present slave view controller like this
SlaveClass *slaveClass = [[SlaveClass alloc] init]
[slaveClass setMyOwnDelegate:self];
[self presentViewController:slaveClas animated:YES completion:nil];
-(void)transferNameDidClick:(NSString *)text
{
// This is the method getting called by the slaveClass. So it should know the delegate to call this.
[_label setText:text];
NSLog(#"text: %#",text);
}
Set you delegate out side the Custom delegate method. you are mistakenly setting inside the custom delegate method thats y delegate show nil. use like this.
Main Class .M
-(IBAction)nextView
{
nextView = [[ViewController2 alloc]init];
nextView.myOwnDelegate = self;
[self presentViewController:nextView animated:YES completion:nil];
}
-(void)transferNameDidClick:(NSString *)text;
{
NSLog(#"Value from Slave Delegate %#",text);
}
SlaveClass.h
#protocol slaveDelegate <NSObject>
-(void)transferNameDidClick:(NSString *)text;
#end
// --------------------------------------------------------------------------------
#interface SlaveClass : UIViewController
#property (nonatomic, strong) id <slaveDelegate> myOwnDelegate;
#end
SlaveClass.m
-(void)buttonDidClick:(id)sender
{
if ([_myOwnDelegate respondsToSelector:#selector(transferNameDidClick:)])
{
[_myOwnDelegate transferNameDidClick:(_textField.text)];
}
}

Resources