1

Given :

  1. classA with its delegate
  2. classB has a button on it
classA.h

@protocol classADelegate <NSObject>
- (void)method:(NSString *) name;
@end
@interface StoreChooser : UIViewController
@end
------------------------------------------------------
classA.m
-(IBAction)buttonCliked{
     // invoke delegate method from classA at here

}

classB.h
@interface classB : UIViewController <classADelegate>
@end

------------------------------------------------------
// Conform delegate of classA
classB.m
- (void)method:(NSString *) name {

} @end ------------------------------------------------------

My goal : I need classB to invoke a method delegate from classA in buttonClicked action

Question : what should I do to achieve my goal.

tranvutuan
  • 6,089
  • 8
  • 47
  • 83

4 Answers4

4

Just to make sure that we are on the same page :)

If ClassA has a delegate ClassADelegate. What this means is that when some "event" occurs in ClassA, ClassA will want to notify some other class via its delegate that the "event" occurred - ClassB. ClassA will do this via its delegate - ClassADelegate.

For this to happen, ClassB will have to let ClassA know that it will be acting as ClassA's delegate. ClassB will have to "conform" to ClassA's protocol by implementing all of the methods listed in the protocol that not marked as @optional.

In code, you could do this:

// ClassA's delegate

@protocol ClassADelegate <NSObject>
- (void) didDoSomethingCool:(NSString *) name;
@end

// ClassA definition

@interface ClassA
// We'll use this property to call the delegate.
// id<XXX> means that which ever class is assigned to id MUST conform to XXX
@property (nonatomic, assign) id<ClassADelegate> classADelegate; 
- (void) doSomething;
@end

// Class A implementation

@implementation ClassA

@synthesize classADelegate;

- (void) doSomething
{
  // Do cool things here.
  // Now call delegate, in this example, this will be ClassB
  [classADelegate didDoSomethingCool:@"Hello from Class A"];
}

Now we need to wire-up ClassB so that it can be notified that something happened in ClassA:

// ClassB definition

@interface ClassB<ClassADelegate>
// ClassB<ClassADelegate> lets the compiler know that ClassB is required to have all the 
// non-optional method that are listed in ClassADelegate. In short, we say that
// ClassB conforms to the ClassADelegate.
{
  ClassA *_classA;
}
@end

Now somewhere in ClassB's implementation file we have the following.

// ClassB implementation

@implementation ClassB

- (id) init
{
  self = [super init];
  if(self)
  {
    // Just quickly creating an instance of ClassA.
    _classA = [ClassA new];
    // This is were we tell ClassA that ClassB is its delegate.
    _classA.classADelegate = self;
  }
  return self;
}

- (void) dealloc
{
  [_classA release];
  [super dealloc]; 
}

- (void) didDoSomethingCool:(NSString *) name
{
  // This is the method that ClassA will be calling via the 
  // [classADelegate didDoSomethingCool:@"Hello from Class A"] method call.
}

@end

I hope this helps :)

haroldcampbell
  • 1,512
  • 1
  • 14
  • 22
2

Add an assign property to classA:

@property (nonatomic, assign) id<classADelegate> delegate; 

Then in the viewDidLoad method for classB, call:

[myClassAObject setDelegate:self];

Then in class A, just call:

if (_delegate && [_delegate respondsToSelector:@selector(method:)]) {
       [_delegate method:@"string"];
}
Andrew
  • 462
  • 5
  • 15
1

ClassB needs a reference to ClassA. This code is not complete but should help you to understand the relationship you need to create.

classB.h

@interface classB: UIViewController <classADelegate>

@property (weak, nonatomic) id<classADelegate> delegate;

@end

classB.m

-(id)init {
    self = [super init];
    if (self) {
        self.delegate = [[classADelegate alloc] init];
    }
}

-(IBAction)buttonClicked {
    [delegate method:@"name"];
}
SteveB
  • 652
  • 3
  • 12
0

You need to store the delegate object in classA:

@interface classA : NSObject
{
    id<classADelegate> _delegate;
}

@property (nonatomic, assign, readwrite) id<classADelegate> delegate;

And synthesize the property:

@implementation classA
...

@synthesize delegate = _delegate;

And then in the method that needs to call the delegate, you need to test the delegate object and method is valid:

- (void)somethingHappened
{
    if ([_delegate respondsToSelector:@selector(method:)])
    {
        [_delegate method:@"Andy"];
    }
}

And finally conform to the delegate protocol in class B:

@implementation classB
...

- (void)method:(NSString *)name
{
    [self buttonCliked:nil];
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242