i try a simple Delegate but the method won't fire. Here is my code:
The view with the protocol and a button which should trigger the delegate:
ViewController.h
#import <UIKit/UIKit.h>
#protocol InitStackDelegate <NSObject>
#required
-(void)initstack:(NSInteger)amount;
#end
#interface ViewController : UIViewController{
IBOutlet UITextField *amountTextField;
__unsafe_unretained id<InitStackDelegate> delegate;
}
- (IBAction)init:(id)sender;
#property (nonatomic,assign)id delegate;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize delegate;
- (IBAction)init:(id)sender {
//send the delegate
[delegate initstack:[amountTextField.text intValue]];
}
AppDelegate.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate,InitStackDelegate> {
}
#property (strong, nonatomic) UIWindow *window;
#property (strong,nonatomic) ViewController *myView;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window;
#synthesize myView;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//..... push second controller into navigation stack
myView.delegate = self;
return YES;
}
...
#pragma mark Delegate Method
-(void)initstack:(NSInteger)amount{
NSInteger test;
}
#end
When i hit the button i get to (IBAction) init but then the delegate do nothing. I set a breakpoint in AppDelegate.m but it is never reached. Any help?
thx
Mario
In you App Delegate, when you set myView.delegate=self myView doesn't actually point to anything!
You need to set myView to point to your ViewController.
Use this in didFinishLaunchingWithOptions
myView = (ViewController *)self.window.rootViewController;
myView.delegate = self;
Related
I know there are tons of questions out there about passing messages between different view controllers. I've checked them all but I can't get it working.
I've followed this tutorial: http://www.youtube.com/watch?v=XZWT0IV8FrI replacing the storyboard with a navigation controller but I run across the following issue over and over again: 'Cannot find protocol declaration for...'
Here is the code:
FirstViewController.h
#import "SecondViewController.h"
#interface FirstViewController : UIViewController <SecondViewControllerDelegate>{
//In this line above is where I get the error 'Cannot find protocol declaration for SecondViewControllerDelegate'
IBOutlet UITextField *userNameTextField;
}
#property (nonatomic, strong) UITextField *userNameTextField;
-(IBAction)goNext:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize userNameTextField;
-(void)goNext:(id)sender{
SecondViewController *secondVC = [[SecondViewController alloc]init];
secondVC.delegate = self;
[self.navigationController pushViewController:secondVC animated:YES];
}
-(void)done:(NSString*)name{
NSLog(#"BACK in firstVC");
userNameTextField.text = name;
}
#end
SecondViewController.h
#import "FirstViewController.h"
#protocol SecondViewControllerDelegate <NSObject>
-(void)done:(NSString*)someText;
#end
#interface SecondViewController : UIViewController{
IBOutlet UITextField *someText;
IBOutlet UIButton *returnButton;
id delegate;
}
#property (assign, nonatomic) id <SecondViewControllerDelegate> delegate;
#property (strong, nonatomic) UITextField *someText;
-(IBAction)goBack:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize someText;
#synthesize delegate = _delegate;
-(void)goBack:(id)sender{
[self.delegate done:someText.text];
FirstViewController *firstVC = [[FirstViewController alloc]init];
[self.navigationController pushViewController:firstVC animated:YES];
}
#end
In your SecondViewController goBack implementation you are creating a new FirstViewController rather than popping your navigation controller, code should read...
-(void)goBack:(id)sender{
[self.delegate done:someText.text];
[self.navigationController popViewControllerAnimated:YES];
}
And also in your SecondViewController.h remover this #import "FirstViewController.h" as it is no longer needed and could be confusing the compiler
Your protocol name is EYSSecondViewControllerDelegate:
#protocol EYSSecondViewControllerDelegate <NSObject>
but you call it SecondViewControllerDelegate in two places:
#interface EYSFirstViewController : UIViewController <SecondViewControllerDelegate>{...
#property (assign, nonatomic) id <SecondViewControllerDelegate> delegate;...
Make sure that the name match and it should works fine.
In SecondViewController.h
remove line id delegate;
In SecondViewController.m
Update code -> [delegate done:someText.text];
'self.' remove
Try it
Since I switched my iOS project to ARC, I keep getting this compiler error:
No visible #interface for 'CDViewController' declares the selector
'setUseAgof:'
In this line:
[self.viewController setUseAgof:false];
In this file:
AppDelegate.m
#import "AppDelegate.h"
#import "MainViewController.h"
#import <Cordova/CDVPlugin.h>
#import "NSString+MD5.h"
#implementation AppDelegate
#synthesize window, viewController;
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
// (...)
[self.viewController setUseAgof:false]; // <-- HERE
// (...)
return YES;
}
#end
Although the method is definitely defined:
MainViewController.h
#import <Cordova/CDVViewController.h>
#import <ADTECHMobileSDK/ADTECHMobileSDK.h>
#interface MainViewController : CDVViewController <ATInterstitialViewDelegate>{
ATInterstitialView *interstitial;
}
- (void)setUseAgof:(BOOL)useAgofParam;
#end
#interface MainCommandDelegate : CDVCommandDelegateImpl
#end
#interface MainCommandQueue : CDVCommandQueue
#end
MainViewController.m
#import "MainViewController.h"
#interface MainViewController()
- (void)setUseAgof:(BOOL)useAgofParam;
#end
#implementation MainViewController
BOOL useAgof = true;
- (void)setUseAgof:(BOOL)useAgofParam
{
NSLog(#"1.) Setting useAgof = %d", (int)useAgofParam);
useAgof = useAgofParam;
}
I don't get it. What's wrong?
Update:
AppDelegate.h
#import <UIKit/UIKit.h>
#import <Cordova/CDVViewController.h>
#import <INFOnlineLibrary/INFOnlineLibrary.h>
#interface AppDelegate : NSObject <UIApplicationDelegate>{}
#property (nonatomic, strong) IBOutlet UIWindow* window;
#property (nonatomic, strong) IBOutlet CDVViewController* viewController;
#end
viewController seems to be declared as pointer of CDVViewController. You are calling a method which is part of MainViewController the class derived from CDVViewController. Method being called is part of derived class and not the base class, hence make viewController pointer of MainViewController instead.
Make sure the viewController property in your AppDelegate has a type of CDVViewController * rather than UIViewController *.
I am trying to set up a system of ViewControllers and navigate between them. I am trying to navigate between DefaultViewController and CreateViewController. I am new to iOS programming, so I am having a hard time figuring this out. I have mainly been trying to use code from the Utility App template. It would be great if someone could spot my mistake!
The log CreateViewController: cancel is reached when I click on my Cancel-button, but DefaultViewController: createViewControllerDidFinish is not.
This is the relevant code:
DefaultViewController.h
#import <UIKit/UIKit.h>
#import <Social/Social.h>
#import "CreateViewController.h"
#interface DefaultViewController : UIViewController <CreateViewControllerDelegate, UIWebViewDelegate> {
...
}
#property (strong, nonatomic) UIWebView *webView;
- (IBAction)create:(id)sender;
#end
CreateViewController.h
#import <UIKit/UIKit.h>
#import <Social/Social.h>
#class CreateViewController;
#protocol CreateViewControllerDelegate
- (void)createViewControllerDidFinish:(CreateViewController *)controller;
#end
#interface CreateViewController : UIViewController <UIWebViewDelegate> {
...
}
#property (weak, nonatomic) id <CreateViewControllerDelegate> delegate;
- (IBAction)cancel:(id)sender;
- (IBAction)submit:(id)sender;
#end
DefaultViewController.m
#import "AppDelegate.h"
#import "DefaultViewController.h"
...
#implementation DefaultViewController
...
#pragma mark - CreateViewController
- (void)createViewControllerDidFinish:(CreateViewController *)controller {
NSLog(#"DefaultViewController: createViewControllerDidFinish");
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)create:(id)sender {
CreateViewController *vc2 = [[CreateViewController alloc] init];
[self.navigationController pushViewController:vc2 animated:YES];
}
#end
CreateViewController.m
#import "AppDelegate.h"
#import "CreateViewController.h"
...
#implementation CreateViewController
...
#pragma mark - Actions
- (IBAction)cancel:(id)sender {
NSLog(#"CreateViewController: cancel");
[self.delegate createViewControllerDidFinish:self];
}
- (IBAction)submit:(id)sender {
[webView stringByEvaluatingJavaScriptFromString:#"EntryCreate.submit();"];
}
#end
Using Navigation Controller,when you push a view controller you have to pop to dismiss
- (IBAction)cancel:(id)sender {
NSLog(#"CreateViewController: cancel");
[self.navigationController popViewControllerAnimated:YES];
}
No need for the controller instance Nav Controller is basically a stack and when you pop it removes from the top of the stack and move to the previous viewcontroller from where it is pushed.
So I have 3 views as follows: viewController >> viewController2 >> viewController3.
In viewController3 I have created a Delegate Protocol. The protocol method is a simple method that prints out an NSLog.
When I call the delegates from ViewController3, only its parent (viewController2 ) responds not the (first) viewController. There are no errors.I think problem has got something to do with [v2 setDelegate:self]; in the viewController.m file.
Nevertheless,[self.v3 setDelegate:self]; works fine in ViewController2.m file.
Why does the (first) viewController delegate not respond ? Do delegates only work with its immediate child ??
> **ViewController.h**
#import <UIKit/UIKit.h>
#import "ViewController2.h"
#import "ViewController2.h"
#interface ViewController : UIViewController <PassData>{
ViewController2 *v2;
}
#property (strong, nonatomic) ViewController2 *v2;
> Blockquote
- (IBAction)button:(id)sender;
#end
> **ViewController.M**
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize v2;
- (IBAction)button:(id)sender {
v2 = [[ViewController2 alloc]initWithNibName:#"ViewController2" bundle:nil];
[v2 setDelegate:self];
[self.view addSubview:v2.view];
}
-(void)print: (BOOL)success;{
if (success == YES) {
NSLog(#"ViewController called");
}
}
#end
> > ViewController2.h
#import <UIKit/UIKit.h>
#import "ViewController3.h"
#interface ViewController2 : UIViewController <PassData> {
ViewController3 *v3;
}
#property (strong, nonatomic)ViewController3 *v3;
#property (retain) id delegate;
- (IBAction)button:(id)sender;
#end
ViewController2.m
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
#synthesize v3,delegate;
- (IBAction)button:(id)sender {
v3 = [[ViewController3 alloc]initWithNibName:#"ViewController3" bundle:nil];
[self.v3 setDelegate:self];
[self.view addSubview:v3.view];
}
-(void)print: (BOOL)success;{
if (success == YES) {
NSLog(#"ViewController2 called");
}
}
#end
> ViewController3.h
#import <UIKit/UIKit.h>
#protocol PassData <NSObject>
#required
-(void)print:(BOOL)success;
#end
#interface ViewController3 : UIViewController {
id<PassData> delegate;
}
#property (retain) id delegate;
- (IBAction)callButton:(id)sender;
#end
ViewController3.m
#import "ViewController3.h"
#interface ViewController3 ()
#end
#implementation ViewController3
#synthesize delegate;
- (IBAction)callButton:(id)sender {
// call all delegates
[[self delegate]print:YES];
}
#end
v2 doesn't have a method "print", that's a protocol method of v3 -- you can't chain delegate messages like this. If you want multiple controllers to respond to something in another controller, then you should use an NSNotification -- any number of objects can register to receive a notification.
I was playing around with MKMap and some custom delegate it's not working here and i really don't know why :/
Here's my code :
LocationViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#protocol LocationViewDelegate <NSObject>
#required
- (void)didReceiveLocation:(CLLocation *)location;
#end
#interface LocationViewController : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) IBOutlet UILabel *locationLabel;
#property (nonatomic, strong) id<LocationViewDelegate> delegate;
- (IBAction)sendLocation:(id)sender;
#end
LocationViewController.m
[...]
- (IBAction)sendLocation:(id)sender {
if ([_delegate respondsToSelector:#selector(didReceiveLocation:)]) {
[_delegate didReceiveLocation:_currentLocation];
} else {
NSLog(#"nope");
}
}
[...]
MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "LocationViewController.h"
#interface MapViewController : UIViewController <LocationViewDelegate>
#end
MapViewController.m
[...]
- (void)didReceiveLocation:(CLLocation *)location {
_mapView.centerCoordinate = location.coordinate;
}
[...]
I'm always getting the "nope" message means that respondsToSelector returns NO.
I did pretty the same example a few days ago and everything was fine.
Someone can see where's the problem here ?
Set your MapViewController as the delegate for the LocationViewController i.e. in your MapViewController.m:
self.locationViewController.delegate = self;
Just as an aside, I'm presuming your MapViewController owns a LocationViewController instance, if so it's better to set the delegate property in LocationViewController to 'weak' to avoid a circular reference. #property (nonatomic, weak) id delegate;