如何在Objective-C中创build委托?

我知道代表是如何工作的,而且我知道如何使用它们。

但是,我如何创build它们?

一个Objective-C委托是一个已经分配给delegate属性另一个对象的对象。 要创build一个,只需定义一个实现您感兴趣的委托方法的类,并将该类标记为实现委托协议。

例如,假设你有一个UIWebView 。 如果你想实现它的委托的webViewDidStartLoad:方法,你可以像这样创build一个类:

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

然后,您可以创build一个MyClass的实例,并将其指定为Web视图的委托:

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

UIWebView方面,它可能具有类似于此的代码,以查看委托是否响应使用respondsToSelector的webViewDidStartLoad:消息:并在适当时发送它。

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

委托属性本身通常被声明为weak (在ARC中)或assign (pre-ARC)以避免保留循环,因为对象的委托经常对该对象持有强引用。 (例如,视图控制器通常是它包含的视图的代表。)

为你的class级做代表

要定义你自己的委托,你必须在某个地方声明他们的方法,正如Apple Docs on protocols所讨论的那样。 你通常会声明一个正式的协议。 声明,从UIWebView.h转述,看起来像这样:

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

这类似于接口或抽象基类,因为它在这种情况下为您的委托UIWebViewDelegate创build了一个特殊的types。 代表实现者必须采用这个协议:

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

然后在协议中实现这些方法。 对于在协议中声明为@optional (像大多数委托方法)的方法,你需要在调用一个特定的方法之前用@optional进行检查。

命名

委托方法通常以委派​​类名开始,并以委托对象作为第一个参数。 他们也经常使用意志,应该,或者forms。 所以, webViewDidStartLoad:第一个参数是web视图),而不是loadStarted (不带参数)。

速度优化

每次我们要发送消息时,不要检查委托是否响应select器,而是可以在代理设置时caching该信息。 一个非常干净的方法是使用一个位域,如下所示:

 @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 

然后,在正文中,我们可以通过访问我们的delegateRespondsTo结构来检查委托是否处理消息,而不是通过发送-respondsToSelector:一遍又一遍。

非正式代表

在协议存在之前,通常在NSObject上使用一个类别来声明一个委托可以实现的方法。 例如, CALayer仍然这样做:

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

这基本上告诉编译器,任何对象都可能实现displayLayer:

然后,您将使用与上述相同的-respondsToSelector:方法来调用此方法。 代表只是简单的实现这个方法,并指定delegate属性,就是这样(没有声明你遵守协议)。 这种方法在Apple的库中很常见,但新代码应该使用上面更现代的协议方法,因为这种方法会污染NSObject (使自动完成function变得不那么有用),并且使编译器很难警告你input错误和类似的错误。

批准的答案是伟大的,但如果你正在寻找1分钟的答案试试这个:

MyClass.h文件应该是这样的(添加注释的代表行!)

 #import <BlaClass/BlaClass.h> @class MyClass; //define class, so protocol can see MyClass @protocol MyClassDelegate <NSObject> //define delegate protocol - (void) myClassDelegateMethod: (MyClass *) sender; //define delegate method to be implemented within another class @end //end protocol @interface MyClass : NSObject { } @property (nonatomic, weak) id <MyClassDelegate> delegate; //define MyClassDelegate as delegate @end 

MyClass.m文件应该像这样

 #import "MyClass.h" @implementation MyClass @synthesize delegate; //synthesise MyClassDelegate delegate - (void) myMethodToDoStuff { [self.delegate myClassDelegateMethod:self]; //this will call the method implemented in your other class } @end 

要在另一个类中使用委托(本例中称为MyVC的UIViewController)MyVC.h:

 #import "MyClass.h" @interface MyVC:UIViewController <MyClassDelegate> { //make it a delegate for MyClassDelegate } 

MyVC.m:

 myClass.delegate = self; //set its delegate to self somewhere 

实现委托方法

 - (void) myClassDelegateMethod: (MyClass *) sender { NSLog(@"Delegates are great!"); } 

当使用正式协议方法创build委托支持时,我发现可以通过添加如下内容来确保正确的types检查(尽pipe是运行时,而不是编译时):

 if (![delegate conformsToProtocol:@protocol(MyDelegate)]) { [NSException raise:@"MyDelegate Exception" format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__]; } 

在你的委托访问器(setDelegate)代码中。 这有助于减less错误。

请! 请查看下面的简单的一步一步的教程,以了解Delegates如何在iOS中工作。

在iOS中委派

我创build了两个ViewController(用于将数据从一个发送到另一个)

  1. FirstViewController实现委托(提供数据)。
  2. SecondViewController声明委托(将接收数据)。

也许这更符合你所缺less的东西:

如果你是来自C ++的观点,代表需要一些习惯 – 但基本上“他们只是工作”。

它的工作方式是设置一些作为NSWindow委托编写的对象,但是对象只有一个或多个可能委托方法的实现(方法)。 所以发生了一些事情, NSWindow想调用你的对象 – 它只是使用Objective-c的respondsToSelector方法来确定你的对象是否需要调用这个方法,然后调用它。 这就是Objective-C的工作原理 – 按需查找方法。

这对你自己的对象来说是微不足道的,没有什么特别的,你可以例如有一个NSArray的27个对象,所有不同types的对象,只有18其中一些具有方法-(void)setToBue; 其他9不。 所以要调用setToBlue的18个需要它的东西,像这样:

 for (id anObject in myArray) { if ([anObject respondsToSelector:@selector(@"setToBlue")]) [anObject setToBlue]; } 

关于委托的另一件事是它们不被保留,所以你总是必须在你的MyClass dealloc方法中设置委托nil

作为苹果公司推荐的一个很好的做法,对于代理(这是一个协议,根据定义)是符合NSObject协议的。

 @protocol MyDelegate <NSObject> ... @end 

&在委托中创build可选的方法(即不需要实现的方法),可以使用@optional注释,如下所示:

 @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 

所以当使用你指定的可选方法时,如果视图(符合你的委托)真正实现了你的可选方法,你需要(在你的类中)检查respondsToSelector

我认为,一旦你了解了代表,所有这些答案都很有意义。 就我个人而言,我来自C / C ++的领域,在像Fortran等程序语言之前,这里是我在C ++范式中find类似的类似物的2分钟。

如果我要向C ++ / Java程序员解释代表,我会说

什么是代表? 这些是静态指向另一个类中的类的指针。 一旦你分配了一个指针,你可以调用该类中的函数/方法。 因此,你的类的一些function是“委托”(在C ++世界 – 指向一个类对象指针)到另一个类。

什么是协议? 从概念上来说,它与作为委托类分配的类的头文件类似。 一个协议是一个明确的方式来定义什么样的方法需要实现的类的指针被设置为一个类中的委托。

我如何在C ++中做类似的事情? 如果你试图用C ++来做到这一点,你可以在类定义中定义指向类(对象)的指针,然后将它们连接到其他类,这些类将提供作为委托给你的基类的附加function。 但是这种布线需要在代码中进行,而且会很笨拙,容易出错。 Objective C只是假设程序员不是最好的维护这个分界线,并提供编译器的限制来执行一个干净的实现。

Swift版本

一个委托只是一个为另一个类做一些工作的类。 请阅读下面的代码,看看有没有这样的愚蠢的(但有希望的启发)Playground的例子,展示了这是如何在Swift中完成的。

 // A protocol is just a list of methods (and/or properties) that must // be used by any class that adopts the protocol. protocol OlderSiblingDelegate: class { // This protocol only defines one required method func getYourNiceOlderSiblingAGlassOfWater() -> String } class BossyBigBrother { // The delegate is the BossyBigBrother's slave. This position can // be assigned later to whoever is available (and conforms to the // protocol). weak var delegate: OlderSiblingDelegate? func tellSomebodyToGetMeSomeWater() -> String? { // The delegate is optional because there might not be anyone // nearby to boss around. return delegate?.getYourNiceOlderSiblingAGlassOfWater() } } // PoorLittleSister conforms to the OlderSiblingDelegate protocol class PoorLittleSister: OlderSiblingDelegate { // This method is repquired by the protocol, but the protocol said // nothing about how it needs to be implemented. func getYourNiceOlderSiblingAGlassOfWater() -> String { return "Go get it yourself!" } } // initialize the classes let bigBro = BossyBigBrother() let lilSis = PoorLittleSister() // Set the delegate // bigBro could boss around anyone who conforms to the // OlderSiblingDelegate protocol, but since lilSis is here, // she is the unlucky choice. bigBro.delegate = lilSis // Because the delegate is set, there is a class to do bigBro's work for him. // bigBro tells lilSis to get him some water. if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater() { print(replyFromLilSis) // "Go get it yourself!" } 

在实际操作中,代表经常在以下情况下使用

  1. 当一个class级需要将一些信息传达给另一个class级的时候
  2. 当一个class级想要让另一个class级去定制它时

除了委托类符合所需的协议之外,这些类不需要事先知道对方的任何信息。

我强烈build议阅读以下两篇文章。 他们帮助我更好地了解代表们,甚至比文件更好。

  • 什么是授权? – 一个Swift开发人员指南
  • 代表如何工作 – Swift开发指南

可以说你有一个你开发的类,并且想要声明一个委托属性,以便能够在发生某些事件时通知它:

 @class myClass; @protocol myClassDelegate <NSObject> -(void)myClass:(MyClass*)myObject requiredEventHandlerWithParameter:(ParamType*)param; @optional -(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param; @end @interface MyClass : NSObject @property(nonatomic,weak)id< MyClassDelegate> delegate; @end 

所以你在MyClass头文件(或者一个单独的头文件)中声明了一个协议,并声明你的委托必须/应该实现的必需/​​可选事件处理程序,然后在MyClasstypes( id< MyClassDelegate> )中声明一个属性,客观的c类符合协议MyClassDelegate ,你会注意到委托属性被声明为弱,这是非常重要的,以防止保留周期(大多数委托保留MyClass实例,所以如果你宣布委托保留,两他们之间将保持对方,他们都不会被释放)。

您还会注意到协议方法将MyClass实例传递给委托作为参数,这是在委托要调用MyClass实例上的某些方法的情况下的最佳实践,并且还有助于委托将自身声明为MyClassDelegate到多个MyClass实例当你在你的ViewController有多个UITableView's实例,并把它们自己声明为一个UITableViewDelegate

在你的MyClass你通过声明事件通知委托,如下所示:

 if([_delegate respondsToSelector:@selector(myClass: requiredEventHandlerWithParameter:)]) { [_delegate myClass:self requiredEventHandlerWithParameter:(ParamType*)param]; } 

你首先检查你的委托是否响应你将要调用的协议方法,以防委托没有实现它,那么应用程序将崩溃(即使协议方法是必需的)。

好吧,这不是真正的问题的答案,但如果你正在查找如何使自己的代表也许更简单可能是一个更好的答案。

我很less执行我的代表,因为我很less需要。 我只能有一个委托对象的委托。 所以如果你希望你的委托进行单向的通信/传递数据,你会比通知好得多。

NSNotification可以将对象传递给多个收件人,使用起来非常简单。 它是这样工作的:

MyClass.m文件应该像这样

 #import "MyClass.h" @implementation MyClass - (void) myMethodToDoStuff { //this will post a notification with myClassData (NSArray in this case) in its userInfo dict and self as an object [[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData" object:self userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]]; } @end 

在另一个类中使用你的通知:添加类作为观察者:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil]; 

实现select器:

 - (void) otherClassUpdatedItsData:(NSNotification *)note { NSLog(@"*** Other class updated its data ***"); MyClass *otherClass = [note object]; //the object itself, you can call back any selector if you want NSArray *otherClassData = [note userInfo][@"myClassData"]; //get myClass data object and do whatever you want with it } 

如果是的话,不要忘记把你的class级作为观察员

 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

这是一个创build委托的简单方法

在.h文件中创build协议。 确保在使用@class的协议之前定义了UIViewController的名称< As the protocol I am going to use is UIViewController class>.

步骤:1:创build一个名为“YourViewController”的新类协议,它将是UIViewController类的子类,并将此类分配给第二个ViewController。

第二步:进入“YourViewController”文件并修改如下:

 #import <UIKit/UIkit.h> @class YourViewController; @protocol YourViewController Delegate <NSObject> @optional -(void)defineDelegateMethodName: (YourViewController *) controller; @required -(BOOL)delegateMethodReturningBool: (YourViewController *) controller; @end @interface YourViewController : UIViewController //Since the property for the protocol could be of any class, then it will be marked as a type of id. @property (nonatomic, weak) id< YourViewController Delegate> delegate; @end 

协议行为中定义的方法可以使用@optional和@required作为协议定义的一部分进行控制。

第三步: 实施代表

  #import "delegate.h" @interface YourDelegateUser () <YourViewControllerDelegate> @end @implementation YourDelegateUser - (void) variousFoo { YourViewController *controller = [[YourViewController alloc] init]; controller.delegate = self; } -(void)defineDelegateMethodName: (YourViewController *) controller { // handle the delegate being called here } -(BOOL)delegateMethodReturningBool: (YourViewController *) controller { // handle the delegate being called here return YES; } @end 

//在调用之前testing方法是否已被定义

  - (void) someMethodToCallDelegate { if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) { [self.delegate delegateMethodName:self]; } } 

要创build您自己的委托,首先您需要创build一个协议并声明必要的方法,而无需执行。 然后将此协议实现到您想要实现委托或委托方法的头类中。

协议必须声明如下:

 @protocol ServiceResponceDelegate <NSObject> - (void) serviceDidFailWithRequestType:(NSString*)error; - (void) serviceDidFinishedSucessfully:(NSString*)success; @end 

这是应该完成一些任务的服务类。 它显示了如何定义委托以及如何设置委托。 在任务完成之后的实现类中,委托的方法被调用。

 @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 

这是通过将委托设置为自身来调用服务类的主视图类。 协议也是在头类中实现的。

 @interface viewController: UIViewController <ServiceResponceDelegate> { ServiceClass* _service; } - (void) go; @end @implementation viewController // //some methods // - (void) go { _service = [[ServiceClass alloc] init]; [_service setDelegate:self]; [_service someTask]; } 

就是这样,通过在这个类中实现委托方法,一旦操作/任务完成,控制就会回来。

免责声明:这是如何创build委托的Swift版本。

那么,代表是什么? …在软件开发中,有一些可重用的解决scheme架构可以帮助解决在特定情况下常见的问题,这些“模板”可以说是最着名的devise模式。 代表是一种devise模式,它允许一个对象在发生特定事件时将消息发送给另一个对象。 设想一个对象A调用一个对象B来执行一个动作。 一旦行动完成,对象A应该知道B已经完成了任务并采取了必要的行动,这可以在代表的帮助下实现!

为了更好的解释,我将向您展示如何创build一个在类之间传递数据的自定义委托,Swift在一个简单的应用程序中,首先下载或克隆这个启动项目并运行它! https://github.com/jamesrochabrun/DelegateTutorial

你可以看到有两个类的应用程序,ViewController A和ViewController B. B有两个视图可以改变ViewController的背景颜色,没有太复杂的东西吗? 那么现在让我们以一种简单的方式来思考,当点击B类的视图时,也改变类A的背景颜色。

问题是这个观点是B类的一部分,对A类不了解,所以我们需要find一个方法来沟通这两个类,这就是代表团的光芒。 我把这个实现分成了6个步骤,所以你可以在需要的时候用它作为备忘单。

第1步:在ClassBVC文件中查找编译指示标记步骤1并添加它

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

第一步是创build一个协议,在这种情况下,我们将在B类中创build协议,在协议内部可以根据您的实现要求创build所需的许多function。 在这种情况下,我们只有一个简单的函数,接受一个可选的UIColor作为参数。 在这个例子中,ClassBVCDelegate是一个很好的习惯,可以在协议中添加delegate这个单词。

第2步:在ClassVBC中查找pragma标记步骤2并添加它

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

这里我们只是为类创build一个委托属性,这个属性必须采用协议types,而且应该是可选的。 此外,您应该在属性之前添加弱关键字,以避免保留周期和潜在的内存泄漏,如果您不知道这意味着什么现在不担心,请记住添加此关键字。

第3步:在ClassBVC的handleTap方法内查找编译标记第3步,并添加它

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

有一件事你应该知道,运行应用程序并点击任何视图,你将不会看到任何新的行为,这是正确的,但我想指出的是,应用程序没有崩溃时调用委托,这是因为我们将其创build为可选值,这就是为什么即使委派不存在也不会崩溃的原因。 让我们现在去ClassAVC文件,并把它,委托。

第4步:在ClassAVC中查找handleTap方法内部的pragma标记步骤4,并将其添加到类的types旁边。

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

现在ClassAVC采用了ClassBVCDelegate协议,你可以看到你的编译器给你一个错误,说“Type”ClassAVC不符合协议“ClassBVCDelegate”,这只意味着你没有使用协议的方法,想象一下当A级采用协议时就像是与B级签订合同,本合同中规定:“任何采用我的类都必须使用我的function!”

快速提示:如果你来自Objective-C的背景,你可能会认为你也可以closures这个错误使得这个方法是可选的,但是令我惊讶的是,也许你是Swift语言不支持可选的协议,如果你想那么你可以为你的协议创build一个扩展,或者在你的协议实现中使用@objc关键字。

就个人而言,如果我必须用不同的可选方法创build一个协议,我宁愿把它分解成不同的协议,这样我会遵循给我的对象一个单一的责任的概念,但它可以根据具体的实现而有所不同。

这里是关于可选方法的好文章。 https://www.avanderlee.com/swift-2-0/optional-protocol-methods/

步骤5:在准备segue方法内部寻找编译标记步骤5并添加它

 //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 } 

在这里,我们只是创build一个ClassBVC的实例,并将其委托给自己,但这里的自我是什么? 好吧,自己是被授权的ClassAVC!

第6步:最后,在ClassAVC中查找pragma第6步,让我们使用协议的function,开始键入func changeBackgroundColor,你会看到它自动为你完成。 你可以在里面添加任何实现,在这个例子中,我们只是改变背景颜色,添加这个。

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

现在运行应用程序!

代表无处不在,你甚至可以毫不留情地使用它们,如果你在过去创build了一个表视图,你使用了委托,很多类的UIKIT也围绕着它们和许多其他的框架,它们解决了这些主要的问题。

  • 避免物体紧密耦合。
  • 修改行为​​和外观,而不需要子类的对象。
  • 允许将任务处理为任意的对象。

恭喜,你只是实现了一个自定义的委托,我知道你可能在想这么多麻烦? 那么,代表团是一个非常重要的devise模式,要了解你是否想成为一名iOS开发人员,并且时刻牢记,他们之间有一对一的关系。

你可以在这里看到原始教程https://medium.com/compileswift/implementing-delegates-in-swift-step-by-step-d3211cbac3ef

代表: – 创build

 @protocol addToCartDelegate <NSObject> -(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added; @end 

发送并请分配代表以查看您正在发送数据

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

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; 

方法:

 -(void)delegateMEthod: (ArgType) arg{ } 
 //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。 在类.m – (void)didRemoveCellWithTag:(NSInteger)标记{NSLog @(“Tag%d”,tag);

}

以我的观点为该委托方法创build单独的类,并且您可以使用所需的位置。

在我的自定义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; 

之后在.m文件中用对象创build数组,

  - (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]; } } }]; } 

这里所有的都是为自定义委托类设置的。之后,你可以在你想要的地方使用这个委托方法。例如…

在我的另一个viewcontroller后导入

创build这样的调用委托方法的动作

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

之后调用这样的委托方法

 - (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; } } 

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 // } }