iphone make personal delegate - iphone

I have this problem....
in my viewcontroller.h I defined my class like this:
myClass* iR;
and after:
#property (nonatomic,retain) IBOutlet myClass* iR;
into myClass.h I added this:
#protocol myClassDelegate <NSObject>
-(void) didLogon:(bool)isLogged;
#end
and after:
#property (nonatomic, assign) id<myClassDelegate> delegate;
now, into my class, in the connectionDidFinishLoading method ( I used a nsurlconnection to retrieve the login data I added this:
[self.delegate didLogon:true];
into myviewcontroller.h:
<myClassDelegate>
and into myviewcontroller.m:
-(void)didLogon:(bool)isLogged{
...
}
but the program go inside the self.delegate didLogon but into myviewcontroller.m didn't go... did you understand why???

Where are you assigning the delegate? You need something like this:
MyViewController *viewController = [[MyViewController alloc] init];
self.delegate = viewController;
Just to be safe, when you call delegate methods, call them like this:
if ([self.delegate respondsToSelector:#selector(didLogon:)]) {
[self.delegate didLogon:YES];
}
That way, if the delegate doesn't support that method, your program won't crash when it doesn't recognize that selector.

Related

Delegates in iOS

I am a newbie to iOS world, so please ignore the obvious.
I am pushing a viewController(HelpViewController) on top of another viewController(MainViewController). When a particular action happens in the HelpViewController, I would like to update a variable inside the MainViewController. I understand for this I need to use delegate.
Here is my delegate header...
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
// Protocol Definition ends here
#interface ViewDelegate : NSObject
{
// Delegate to respond back
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id delegate;
-(void)sendMessage:(BOOL)status; // Instance method
#end
and implementation...
#implementation ViewDelegate
#synthesize delegate;
-(id)init {
self = [super init];
return self;
}
-(void)sendMessage:(BOOL)status
{
[delegate switchToggled:status];
}
- (void)dealloc
{
[super dealloc];
}
#end
So Now If I want to implement Protocol ViewControllerDelegate I need to specify in MainViewController, which I do as follows --
MainViewController <ViewControllerDelegate>
and
#pragma mark - ViewControllerDelegate delegate
-(void)switchToggled:(BOOL)status{
NSLog(#"Switch Toggled(%d) Message passed to MainViewController",status);
}
My question is how do I specify Object, which delegate property needs to point to, so that it can come back to MainViewController's "switchToggled".
One way I do is by having property inside HelpViewController as follows -
MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.mainView = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
HelpViewController.h
#property (nonatomic) MainViewController *mainView;
HelpViewController.m
#synthesize mainView;
ViewDelegate *myDelegate = [[ViewDelegate alloc] init];
// assign delegate
myDelegate.delegate = mainView;
[myDelegate sendMessage];
[myDelegate release];
Is this correct way to implement or there is better way to achieve this or am I totally wrong.
Thanks
You should do:
// HelpViewController.h
#protocol HelpDelegate
- (void)switchToggled:(BOOL)status;
#end
// HelpViewController.m
#interface HelpViewController : UIViewController
#property (nonatomic, assign) id<HelpDelegate> delegate;
- (id)initWithDelegate:(id<HelpDelegate>)delegate
#end
#implementation HelpViewController
- (id)initWithDelegate:(id<HelpDelegate>)delegate
{
if (self = [super init])
{
self.delegate = delegate;
}
}
- (void)sendMessage:(BOOL)status
{
[self.delegate switchToggled:status];
}
// MainViewController.h
#import "HelpViewController.h"
#interface MainViewController.h : UIViewController <HelpDelegate>
// MainViewController.m
- (void)someMethod
{
HelpViewController* viewController;
viewController = [HelpViewController alloc] initWithDelegate:self];
...
}
#pragma mark - Help Delegate
- (void)switchToggled:(BOOL)status
{
...
}
Give the delegate a name that makes clear to which class it belongs.
You don't need the extra class/files for ViewDelegate/ViewControllerDelegate. Just define the delegate in header of class it belongs to: HelpViewController.n in this case.
Similar: Implement the delegate method switchToggled: in the real class MainViewController, and not in the extra/unnecessary class ViewDelegate.
The purpose of delegates is to avoid class dependencies. By including MainViewController in HelpViewController you create such a dependency. This is not necessary as I show, and is wrong design.
You were also creating a circular dependency, because MainViewController already needed HelpViewController in order to show it, and now they need each other the other way around for sending the event.
Alternatively you can make HelpViewController's delegate public, have an init without argument, and expect users to set it with helpViewController.delegate = self; or something. But this would only make sense when the delegate being set is optional (which don't seems the case here, so adding it to the init method is appropriate).
I tell you what I would have done:
1) the protocol definition is ok, but do NOT create the class ViewDelegate, so:
//ViewControllerDelegate.h
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
2) Your implementation of the delegate method in MainViewController is ok.
3) Now... the important point:
//interface
#interface HelpViewController : UIViewController //or whatever superclass..
{
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id<ViewControllerDelegate> delegate;
#end
//implementation
#implementation HelpViewController
- (void)someMethodWhichCallsTheDelegate
{
//do something
...
// call delegate
//if switchToggled: were optional then add the following
//if ([self.delegate respondToSelector:#selector(switchToggled:)]) {
[self.delegate switchToggled:status];
}
#end
4) Now you have to assign the delegate:
//MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.delegate = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
And that's it!
BTW: if this delegate is related only to HelpViewControllerthen add the protocol definition where you define the interface of the class, it is not necessary to create a separate header file. If instead the protocol is "global", then it can have some sense to declare it separately.

How to call a method from a UIViewController thats already on the UINavigationController stack

I have a UIViewController on a UINavigationStack and from this UIView I load another view not onto the stack but as a subview. This view that I load is just a preferences view for the app that I overlay onto what ever is showing.
i.e.
myViewController <- on the stack button touch loads as a subview to myViewController
+ prefrencesViewController
My question is, is there a way to call a method thats in myViewController from prefrencesViewController? I am trying to use delegates and protocols but its not working, so I am hoping there is either an easy way to do this I don't know about yet or maybe I could get some help with my delegate/protocol...
This is what my code looks like for delegate and protocol set up
//prefrencesViewController.h
#protocol GetPrefrencesViewControllerDelegate <NSObject>
-(void)reloadViewFromSavedPrefrences;
#end
//delegates and protocols
#property (nonatomic, weak) id <GetPrefrencesViewControllerDelegate> delegate;
//prefrencesViewController.m
//delegates and protocols
#synthesize delegate;
//.. inside button action
[[self delegate] reloadViewFromSavedPrefrences];
//myViewController.h
#import "prefrencesViewController.h"
#interface myViewController : UIViewController <UITabBarDelegate, GetGUIEncodedData, GetPrefrencesViewControllerDelegate> {
// prefrencesViewController set up
prefrencesViewController *pvc;
#property (strong, nonatomic) prefrencesViewController *pvc;
//myViewontroller.h
#synthesize pvc;
- (void)viewDidLoad
{
//..
[pvc setDelegate:self];
}
//Delegate and prefrences.. Saved pressed reload the view here.
-(void)reloadViewFromSavedPrefrences {
NSLog(#"WORKED");
}
any help would be greatly appreciated
I'm not sure that you are following the steps that I will present below but if you don't here is the example.
PresentedViewController.h
//import stuff
#protocol PresentedViewControllerDelegate <NSObject>
-(void)methodThatSouldBeImplementedByOtherController; //you can add params
#end
#interface PresentedViewController : UIViewController {
//instance variables
}
#property (nonatomic, assign(week for ARK)) id<PresentedViewControllerDelegate>delegate
//public methods here
PresentedViewController.m
#implementation PresentedViewController
#synthesize delegate;
//method implementation here
-(IBAction)buttonThatWillCallTheDelegate:(id)sender {
if([self.delegate respondsToSelector:#selector(methodThatSouldBeImplementedByOtherController)]) {
[self.delegate methodThatSouldBeImplementedByOtherController];
}
}
ControllerThatWillPresent.h
#interface ControllerThatWillPresent : UIViewController <PresentedViewControllerDelegate> {
//instance variables
}
//some methods maybe
ControllerThatWillPresen.m
#implementation ControllerThatWillPresen
-(void)methodThatWillShowTheVC {
PresentedViewController *vc = [PresentedViewController alloc] init]; //initWithNibname...
vc.delegate = self;
//presentVc, pushVc, addChild ...
}
-(void)methodThatSouldBeImplementedByOtherController {
//do stuff in delegate method
}

IOS setting a custom delegate

I'm working through the IOS HelloWorld example and I have a question regarding setting the delegate for a TextField. In the example it was as easy as control-dragging from the TextField to the ViewController. But now say I wanted to create a custom class to act as my delegate as so:
#import <Foundation/Foundation.h>
#interface SweetAssDelegate : NSObject <UITextFieldDelegate>
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField;
#end
#import "SweetAssDelegate.h"
#implementation SweetAssDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
NSLog(#"Calling Delegate");
[theTextField resignFirstResponder];
return YES;
}
#end
How can I set this class to be the delegate of the TextField? As far as I can tell there is not way to accomplish this through the GUI. I tried manually setting the delegation after window load with no success:
#import "ViewController.h"
#import "SweetAssDelegate.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *inputField;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
SweetAssDelegate *foo = [[SweetAssDelegate alloc] init];
[self.inputField setDelegate:foo];
NSLog(#"Delegate: %#", self.inputField.delegate);
}
I actually receive some sort of memory exception when bringing up the keyboard? Any ideas? Thanks.
As a side question, where should I always use viewDidLoad to initialize any variables? I noticed that init was not being called???
Your delegate object, foo, is allowed to fall out of scope and is released at the end of viewDidLoad and by the time the keyboard comes up, it doesn't exist anymore. Make it an ivar (or property) of your view controller, or otherwise make sure that foo doesn't fall out of scope at the end of viewDidLoad.
Thus, it could be something like:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *inputField;
#property (strong, nonatomic) SweetAssDelegate *foo;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
self.foo = [[SweetAssDelegate alloc] init];
[self.inputField setDelegate:self.foo];
NSLog(#"Delegate: %#", self.inputField.delegate);
}
Your textfield delegate must have the implemented to be your textfield delegate I guess.
A delegate manages the communication between objects, which means your custom delegate must allow communication between objects and must provide methods, the textfield can work with...
Another example is a tableView:
You can make a custom delegate which implements the delegates and then calls some tableview related Methods...
Here this code might be interesting for you:
#interface myCustomDelegateForTextFields <UITextFieldDelegate>
#end
#implementation myCustomDelegateForTextFields
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
return TRUE;
}
#end
#implementation ViewController
myCustomDelegateForTextFields *txtfielddelegate = [[myCustomDelegateForTextFields alloc] init];
UITextField *whatever;
whatever.delegate = txtfielddelegate;
//your textfield now listens to the BOOL method in your custom delegate
#end
Is it that what u were looking for? :)
you can ofc pack the myCustomDelegateForTextField delegate in another class and call the class

how to get its own view controller inside itself?

#interface RecentPhotosViewController () <PhotoViewControllerDelegate>
- (void)viewDidLoad
{
[super viewDidLoad];
[[self.tabBarController.viewControllers objectAtIndex:1] setDelegate:self];
}
The RecentPhotosViewController is a tableviewcontroller which implements a delegate.
I want to set self(RecentPhotosViewController) as the delegate in vieDidLoad(), but when i tried to type:self.setDelegate it turned out self doesn't have this setDelegate method, then i tried this:[[self.tabBarController.viewControllers objectAtIndex:1] setDelegate:self];(this tableview is one of the viewcontrollers of the tabBarControllers.
Then i got an error:[RecentPhotosViewController setDelegate:]: unrecognized selector sent to instance 0xc939960. I don't know how to fix this.
Do this:
#interface RecentPhotosViewController
//etc.
#property (nonatomic, assign) id delegate;
#end
#implementation RecentPhotosViewController
// etc.
#synthesize delegate;
#end

Custom Delegate Issues

my protocol method isn't called ... i'm new in obj-c programming ...
i have a header file for protocol
..........CanUpdateTime.h .....................
#import <Foundation/Foundation.h>
#protocol CanUpdateTime
-(BOOL)canUpdateTime;
#end
..............class interface where i declare my delegate variable and set it's property ..............
#import <UIKit/UIKit.h>
#import "Currency.h"
#import "CanUpdateTime.h"
#protocol CanUpdateTime;
#interface CurrencyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource > {
Currency *currency;
UILabel *dayMonthYear;
id <CanUpdateTime> update;
}
#property (nonatomic, retain) Currency *currency;
#property (nonatomic, retain) IBOutlet UILabel *dayMonthYear;
#property (nonatomic, assign) id <CanUpdateTime> update;
........ implementation file ..............
-(void)viewDidLoad {
[[self update]canUpdateTime];
}
..... the class where i placed the definition of delegate method ...
#interface ExchangeRatesProvider : NSObject <NSXMLParserDelegate,CanUpdateTime> {
and so on ...
}
.... implementation file ..................
-(BOOL)canUpdateTime {
NSLog (#"ok");
return YES;
}
but nothing happens ... i tried to pass to de update(delegate) respondsToSelector method but
nothing happens ... my delegate method doesnt respond ... any ideas ... ???
p.s. sorry for my english ... thanks for attention ...
In ExchangeRatesProvider you should set the delegate for CurrencyViewController as
currencyController.update = self;
where currencyController is an instance of CurrencyViewController
My best guess is that your update variable has never been filled with an ExchangeRatesProvider instance.
At some point in your code and before calling [[self update] canUpdateTime] you need to put an object that conforms to your protocol in the variable.
Looking at your code I think the missing line here is :
ExchangeRatesProvider* provider = [[ExchangeRatesProvider alloc] init];
[[self setUpdate:provider];
These lines can be at the very beginning of viewDidLoad or in the init method.
Don't forget to release the provider when you're done with it with a [self setUpdate:nil]