Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 443 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I create delegates in Objective-C?

#11
Delegate :- Create

@protocol addToCartDelegate <NSObject>

-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;

@end

Send and please assign delegate to view you are sending data

[self.delegate addToCartAction:itemsModel isAdded:YES];

Reply

#12
ViewController.h

@protocol NameDelegate <NSObject>

-(void)delegateMEthod: (ArgType) arg;

@end

@property id <NameDelegate> delegate;

ViewController.m

[self.delegate delegateMEthod: argument];

MainViewController.m

ViewController viewController = [ViewController new];
viewController.delegate = self;
Method:

-(void)delegateMEthod: (ArgType) arg{
}
Reply

#13
As a good practice recommended by Apple, it's good for the delegate (which is a protocol, by definition), to conform to `NSObject` protocol.

@protocol MyDelegate <NSObject>
...
@end

& to create optional methods within your delegate (i.e. methods which need not necessarily be implemented), you can use the `@optional` annotation like this :

@protocol MyDelegate <NSObject>
...
...
// Declaration for Methods that 'must' be implemented'
...
...
@optional
...
// Declaration for Methods that 'need not necessarily' be implemented by the class conforming to your delegate
...
@end

So when using methods that you have specified as optional, you need to (in your class) check with `respondsToSelector` if the view (that is conforming to your delegate) has actually implemented your optional method(s) or not.
Reply

#14


//1.
//Custom delegate
@protocol TB_RemovedUserCellTag <NSObject>

-(void)didRemoveCellWithTag:(NSInteger)tag;

@end

//2.
//Create a weak reference in a class where you declared the delegate
@property(weak,nonatomic)id <TB_RemovedUserCellTag> removedCellTagDelegate;

//3.
// use it in the class
[self.removedCellTagDelegate didRemoveCellWithTag:self.tag];

//4. import the header file in the class where you want to conform to the protocol
@interface MyClassUsesDelegate ()<TB_RemovedUserCellTag>

@end

//5. Implement the method in the class .m
-(void)didRemoveCellWithTag:(NSInteger)tag
{
NSLog@("Tag %d",tag);

}

Reply

#15
In my point of view create separate class for that delegate method and you can use where you want.

in my Custom DropDownClass.h

typedef enum
{
DDSTATE,
DDCITY
}DropDownType;

@protocol DropDownListDelegate <NSObject>
@required
- (void)dropDownDidSelectItemWithString:(NSString*)itemString DropDownType:(DropDownType)dropDownType;
@end
@interface DropDownViewController : UIViewController
{
BOOL isFiltered;
}
@property (nonatomic, assign) DropDownType dropDownType;
@property (weak) id <DropDownListDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *array1DropDown;
@property (strong, nonatomic) NSMutableArray *array2DropDown;

after that in.m file create array with objects,

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat rowHeight = 44.0f;
return rowHeight;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return isFiltered?[self.array1DropDown count]:[self.array2DropDown count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

if (self.delegate) {
if (self.dropDownType == DDCITY) {
cell.textLabel.text = [self.array1DropDown objectAtIndex:indexPath.row];
}
else if (self.dropDownType == DDSTATE) {
cell.textLabel.text = [self.array2DropDown objectAtIndex:indexPath.row];
}
}
return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self dismissViewControllerAnimated:YES completion:^{
if(self.delegate){
if(self.dropDownType == DDCITY){
[self.delegate dropDownDidSelectItemWithString:[self.array1DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
}
else if (self.dropDownType == DDSTATE) {
[self.delegate dropDownDidSelectItemWithString:[self.array2DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
}
}
}];
}

Here all are set for Custom delegate class.after that you can use this delegate method where you want.for example...

in my another viewcontroller import <DropDownListDelegate>after that

create action for calling delegate method like this

- (IBAction)dropDownBtn1Action:(id)sender {
DropDownViewController *vehicleModelDropView = [[DropDownViewController alloc]init];
vehicleModelDropView.dropDownType = DDCITY;
vehicleModelDropView.delegate = self;
[self presentViewController:vehicleModelDropView animated:YES completion:nil];
}
after that call delegate method like this

- (void)dropDownDidSelectItemWithString:(NSString *)itemString DropDownType:(DropDownType)dropDownType {
switch (dropDownType) {
case DDCITY:{
if(itemString.length > 0){
//Here i am printing the selected row
[self.dropDownBtn1 setTitle:itemString forState:UIControlStateNormal];
}
}
break;
case DDSTATE: {
//Here i am printing the selected row
[self.dropDownBtn2 setTitle:itemString forState:UIControlStateNormal];
}

default:
break;
}
}
Reply

#16
Let's start with an example , if we buy a product online ,it goes through process like shipping/delivery handled by different teams.So if shipping gets completed ,shipping team should notify delivery team & it should be one to one communication as broadcasting this information would be overhead for other people / vendor might want to pass this information only to required people.

So if we think in terms of our app, an event can be an online order & different teams can be like multiple views.

Here is code consider ShippingView as Shipping team & DeliveryView as delivery team :

//Declare the protocol with functions having info which needs to be communicated
protocol ShippingDelegate : class {
func productShipped(productID : String)
}
//shippingView which shows shipping status of products
class ShippingView : UIView
{

weak var delegate:ShippingDelegate?
var productID : String

@IBAction func checkShippingStatus(sender: UIButton)
{
// if product is shipped
delegate?.productShipped(productID: productID)
}
}
//Delivery view which shows delivery status & tracking info
class DeliveryView: UIView,ShippingDelegate
{
func productShipped(productID : String)
{
// update status on view & perform delivery
}
}

//Main page on app which has both views & shows updated info on product whole status
class ProductViewController : UIViewController
{
var shippingView : ShippingView
var deliveryView : DeliveryView

override func viewDidLoad() {
super.viewDidLoad()
// as we want to update shipping info on delivery view, so assign delegate to delivery object
// whenever shipping status gets updated it will call productShipped method in DeliveryView & update UI.
shippingView.delegate = deliveryView
//
}
}

Reply

#17
To create your own delegate, first you need to create a protocol and declare the necessary methods, without implementing. And then implement this protocol into your header class where you want to implement the delegate or delegate methods.

A protocol must be declared as below:

@protocol ServiceResponceDelegate <NSObject>

- (void) serviceDidFailWithRequestType:(NSString*)error;
- (void) serviceDidFinishedSucessfully:(NSString*)success;

@end

This is the service class where some task should be done. It shows how to define delegate and how to set the delegate. In the implementation class after the task is completed the delegate's the methods are called.

@interface ServiceClass : NSObject
{
id <ServiceResponceDelegate> _delegate;
}

- (void) setDelegate:(id)delegate;
- (void) someTask;

@end

@implementation ServiceClass

- (void) setDelegate:(id)delegate
{
_delegate = delegate;
}

- (void) someTask
{
/*

perform task

*/
if (!success)
{
[_delegate serviceDidFailWithRequestType:@”task failed”];
}
else
{
[_delegate serviceDidFinishedSucessfully:@”task success”];
}
}
@end

This is the main view class from where the service class is called by setting the delegate to itself. And also the protocol is implemented in the header class.

@interface viewController: UIViewController <ServiceResponceDelegate>
{
ServiceClass* _service;
}

- (void) go;

@end

@implementation viewController

//
//some methods
//

- (void) go
{
_service = [[ServiceClass alloc] init];
[_service setDelegate:self];
[_service someTask];
}


That's it, and by implementing delegate methods in this class, control will come back once the operation/task is done.
Reply

#18
Disclaimer: this is the `Swift` version of how to create a `delegate`.

So, what are delegates? …in software development, there are general reusable solution architectures that help to solve commonly occurring problems within a given context, these “templates”, so to speak, are best known as design patterns.
Delegates are a design pattern that allows one object to send messages to another object when a specific event happens.
Imagine an object A calls an object B to perform an action. Once the action is complete, object A should know that B has completed the task and take necessary action, this can be achieved with the help of delegates!

For a better explanation, I am going to show you how to create a custom delegate that passes data between classes, with Swift in a simple application,[start by downloading or cloning this starter project and run it!][1]

You can see an app with two classes, `ViewController A` and `ViewController B`. B has two views that on tap changes the background color of the `ViewController`, nothing too complicated right? well now let’s think in an easy way to also change the background color of class A when the views on class B are tapped.

The problem is that this views are part of class B and have no idea about class A, so we need to find a way to communicate between this two classes, and that’s where delegation shines.
I divided the implementation into 6 steps so you can use this as a cheat sheet when you need it.

step 1: Look for the pragma mark step 1 in ClassBVC file and add this

//MARK: step 1 Add Protocol here.
protocol ClassBVCDelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}

The first step is to create a `protocol`, in this case, we will create the protocol in class B, inside the protocol you can create as many functions that you want based on the requirements of your implementation. In this case, we just have one simple function that accepts an optional `UIColor` as an argument.
Is a good practice to name your protocols adding the word `delegate` at the end of the class name, in this case, `ClassBVCDelegate`.

step 2: Look for the pragma mark step 2 in `ClassVBC` and add this

//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?

Here we just create a delegate property for the class, this property must adopt the `protocol` type, and it should be optional. Also, you should add the weak keyword before the property to avoid retain cycles and potential memory leaks, if you don’t know what that means don’t worry for now, just remember to add this keyword.

step 3: Look for the pragma mark step 3 inside the handleTap `method` in `ClassBVC` and add this

//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)

One thing that you should know, run the app and tap on any view, you won’t see any new behavior and that’s correct but the thing that I want to point out is that the app it’s not crashing when the delegate is called, and it’s because we create it as an optional value and that’s why it won’t crash even the delegated doesn’t exist yet. Let’s now go to `ClassAVC` file and make it, the delegated.

step 4: Look for the pragma mark step 4 inside the handleTap method in `ClassAVC` and add this next to your class type like this.

//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {
}

Now ClassAVC adopted the `ClassBVCDelegate` protocol, you can see that your compiler is giving you an error that says “Type ‘ClassAVC does not conform to protocol ‘ClassBVCDelegate’ and this only means that you didn’t use the methods of the protocol yet, imagine that when class A adopts the protocol is like signing a contract with class B and this contract says “Any class adopting me MUST use my functions!”

Quick note: If you come from an `Objective-C` background you are probably thinking that you can also shut up that error making that method optional, but for my surprise, and probably yours, `Swift` language does not support optional `protocols`, if you want to do it you can create an extension for your `protocol` or use the @objc keyword in your `protocol` implementation.

Personally, If I have to create a protocol with different optional methods I would prefer to break it into different `protocols`, that way I will follow the concept of giving one single responsibility to my objects, but it can vary based on the specific implementation.

[here is][2] a good article about optional methods.


step 5: Look for the pragma mark step 5 inside the prepare for segue method and add this

//MARK: step 5 create a reference of Class B and bind them through the `prepareforsegue` method.
if let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC {
classBVC.delegate = self
}

Here we are just creating an instance of `ClassBVC` and assign its delegate to self, but what is self here? well, self is the `ClassAVC` which has been delegated!

step 6: Finally, look for the pragma step 6 in `ClassAVC` and let’s use the functions of the `protocol`, start typing func **changeBackgroundColor** and you will see that it’s auto-completing it for you. You can add any implementation inside it, in this example, we will just change the background color, add this.

//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}

Now run the app!

`Delegates` are everywhere and you probably use them without even notice, if you create a `tableview` in the past you used delegation, many classes of `UIKIT` works around them and many other `frameworks` too, they solve these main problems.

- Avoid tight coupling of objects.
- Modify behavior and appearance without the need to subclass objects.
- Allow tasks to be handled off to any arbitrary object.

Congratulations, you just implement a custom delegate, I know that you are probably thinking, so much trouble just for this? well, delegation is a very important design pattern to understand if you want to become an `iOS` developer, and always keep in mind that they have one to one relationship between objects.

You can see the original tutorial [here][3]


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#19
Answer is actually answered, but I would like to give you a "cheat sheet" for creating a delegate:

DELEGATE SCRIPT

CLASS A - Where delegate is calling function

@protocol <#Protocol Name#> <NSObject>

-(void)delegateMethod;

@end

@interface <#Some ViewController#> : <#UIViewController#>

@property (nonatomic, assign) id <<#Protocol Name#>> delegate;

@end


@implementation <#Some ViewController#>

-(void)someMethod {
[self.delegate methodName];
}

@end




CLASS B - Where delegate is called

@interface <#Other ViewController#> (<#Delegate Name#>) {}
@end

@implementation <#Other ViewController#>

-(void)otherMethod {
CLASSA *classA = [[CLASSA alloc] init];

[classA setDelegate:self];
}

-delegateMethod() {

}

@end

Reply

#20
An Objective-C delegate is an object that has been assigned to the `delegate` property another object. To create one, you define a class that implements the delegate methods you're interested in, and mark that class as implementing the delegate protocol.

For example, suppose you have a `UIWebView`. If you'd like to implement its delegate's [`webViewDidStartLoad:`](

[To see links please register here]

) method, you could create a class like this:

@interface MyClass<UIWebViewDelegate>
// ...
@end

@implementation MyClass
- (void)webViewDidStartLoad:(UIWebView *)webView {
// ...
}
@end

Then you could create an instance of MyClass and assign it as the web view's delegate:

MyClass *instanceOfMyClass = [[MyClass alloc] init];
myWebView.delegate = instanceOfMyClass;

On the `UIWebView` side, it probably has code similar to this to see if the delegate responds to the `webViewDidStartLoad:` message using [`respondsToSelector:`](

[To see links please register here]

) and send it if appropriate.

if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
[self.delegate webViewDidStartLoad:self];
}

The delegate property itself is typically declared `weak` (in ARC) or `assign` (pre-ARC) to avoid retain loops, since the delegate of an object often holds a strong reference to that object. (For example, a view controller is often the delegate of a view it contains.)

## Making Delegates for Your Classes

To define your own delegates, you'll have to declare their methods somewhere, as discussed in the [Apple Docs on protocols](

[To see links please register here]

). You usually declare a formal protocol. The declaration, paraphrased from UIWebView.h, would look like this:

@protocol UIWebViewDelegate <NSObject>
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end

This is analogous to an interface or abstract base class, as it creates a special type for your delegate, `UIWebViewDelegate` in this case. Delegate implementors would have to adopt this protocol:

@interface MyClass <UIWebViewDelegate>
// ...
@end

And then implement the methods in the protocol. For methods declared in the protocol as `@optional` (like most delegate methods), you need to check with `-respondsToSelector:` before calling a particular method on it.

### Naming

Delegate methods are typically named starting with the delegating class name, and take the delegating object as the first parameter. They also often use a will-, should-, or did- form. So, `webViewDidStartLoad:` (first parameter is the web view) rather than `loadStarted` (taking no parameters) for example.

### Speed Optimizations

Instead of checking whether a delegate responds to a selector every time we want to message it, you can cache that information when delegates are set. One very clean way to do this is to use a bitfield, as follows:

@protocol SomethingDelegate <NSObject>
@optional
- (void)something:(id)something didFinishLoadingItem:(id)item;
- (void)something:(id)something didFailWithError:(NSError *)error;
@end

@interface Something : NSObject
@property (nonatomic, weak) id <SomethingDelegate> delegate;
@end

@implementation Something {
struct {
unsigned int didFinishLoadingItem:1;
unsigned int didFailWithError:1;
} delegateRespondsTo;
}
@synthesize delegate;

- (void)setDelegate:(id <SomethingDelegate>)aDelegate {
if (delegate != aDelegate) {
delegate = aDelegate;

delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)];
delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];
}
}
@end

Then, in the body, we can check that our delegate handles messages by accessing our `delegateRespondsTo` struct, rather than by sending `-respondsToSelector:` over and over again.

### Informal Delegates

Before protocols existed, it was common to use a [category](

[To see links please register here]

) on `NSObject` to declare the methods a delegate could implement. For example, `CALayer` still does this:

@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end

This tells the compiler that any object might implement `displayLayer:`.

You would then use the same `-respondsToSelector:` approach as described above to call this method. Delegates implement this method and assign the `delegate` property, and that's it (there's no declaring you conform to a protocol). This method is common in Apple's libraries, but new code should use the more modern protocol approach above, since this approach pollutes `NSObject` (which makes autocomplete less useful) and makes it hard for the compiler to warn you about typos and similar errors.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through