如何设置一个简单的委托来在两个视图控制器之间进行通信?

我有两个 UITableViewControllers,需要使用委托将值从子视图控制器传递给父级。我知道什么是代表,只是想看一个简单的示例。

谢谢你

134287 次浏览

您需要使用委托和协议

举个简单的例子。

假设子视图控制器有一个 UISlider,我们希望通过一个委托将滑块的值传递回父级。

在子视图控制器的头文件中,声明委托类型及其方法:

ChildViewController

#import <UIKit/UIKit.h>


// 1. Forward declaration of ChildViewControllerDelegate - this just declares
// that a ChildViewControllerDelegate type exists so that we can use it
// later.
@protocol ChildViewControllerDelegate;


// 2. Declaration of the view controller class, as usual
@interface ChildViewController : UIViewController


// Delegate properties should always be weak references
// See http://stackoverflow.com/a/4796131/263871 for the rationale
// (Tip: If you're not using ARC, use `assign` instead of `weak`)
@property (nonatomic, weak) id<ChildViewControllerDelegate> delegate;


// A simple IBAction method that I'll associate with a close button in
// the UI. We'll call the delegate's childViewController:didChooseValue:
// method inside this handler.
- (IBAction)handleCloseButton:(id)sender;


@end


// 3. Definition of the delegate's interface
@protocol ChildViewControllerDelegate <NSObject>


- (void)childViewController:(ChildViewController*)viewController
didChooseValue:(CGFloat)value;


@end

在子视图控制器的实现中,根据需要调用委托方法。

ChildViewController.m

#import "ChildViewController.h"


@implementation ChildViewController


- (void)handleCloseButton:(id)sender {
// Xcode will complain if we access a weak property more than
// once here, since it could in theory be nilled between accesses
// leading to unpredictable results. So we'll start by taking
// a local, strong reference to the delegate.
id<ChildViewControllerDelegate> strongDelegate = self.delegate;


// Our delegate method is optional, so we should
// check that the delegate implements it
if ([strongDelegate respondsToSelector:@selector(childViewController:didChooseValue:)]) {
[strongDelegate childViewController:self didChooseValue:self.slider.value];
}
}


@end

在父视图控制器的头文件中,声明它实现了 ChildViewControllerDelegate协议。

RootViewController. h

#import <UIKit/UIKit.h>
#import "ChildViewController.h"


@interface RootViewController : UITableViewController <ChildViewControllerDelegate>


@end

在父视图控制器的实现中,适当地实现委托方法。

RootViewController.m

#import "RootViewController.h"


@implementation RootViewController


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ChildViewController *detailViewController = [[ChildViewController alloc] init];
// Assign self as the delegate for the child view controller
detailViewController.delegate = self;
[self.navigationController pushViewController:detailViewController animated:YES];
}


// Implement the delegate methods for ChildViewControllerDelegate
- (void)childViewController:(ChildViewController *)viewController didChooseValue:(CGFloat)value {


// Do something with value...


// ...then dismiss the child view controller
[self.navigationController popViewControllerAnimated:YES];
}


@end

希望这个能帮上忙!

下面的代码展示了委托概念的基本用法。.根据需要命名变量和类。

首先,你需要声明一个协议:

我们叫它 MyFirstControllerGenerate.h

@protocol MyFirstControllerDelegate
- (void) FunctionOne: (MyDataOne*) dataOne;
- (void) FunctionTwo: (MyDatatwo*) dataTwo;
@end

导入 MyFirstControllerGenerate.h文件并用协议 MyFirstController 委托确认 第一控制器

#import "MyFirstControllerDelegate.h"


@interface FirstController : UIViewController<MyFirstControllerDelegate>
{


}


@end

在实现文件中,您需要实现协议的两个功能:

@implementation FirstController




- (void) FunctionOne: (MyDataOne*) dataOne
{
//Put your finction code here
}
- (void) FunctionTwo: (MyDatatwo*) dataTwo
{
//Put your finction code here
}


//Call below function from your code
-(void) CreateSecondController
{
SecondController *mySecondController = [SecondController alloc] initWithSomeData:.];
//..... push second controller into navigation stack
mySecondController.delegate = self ;
[mySecondController release];
}


@end

在你的 第二总监:

@interface SecondController:<UIViewController>
{
id <MyFirstControllerDelegate> delegate;
}


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


@end

第二总监的实现文件中。

@implementation SecondController


@synthesize delegate;
//Call below two function on self.
-(void) SendOneDataToFirstController
{
[delegate FunctionOne:myDataOne];
}
-(void) SendSecondDataToFirstController
{
[delegate FunctionTwo:myDataSecond];
}


@end

这里 是 wiki 上的一篇关于委托的文章。

下面的解决方案是使用委托将数据从 VC2发送到 VC1的非常基本和简单的方法。

PS: 这个解决方案是用 Xcode 9.X 和 Swift 4制作的

声明了一个协议并在 ViewControllerB中创建了一个 授权变量

    import UIKit


//Declare the Protocol into your SecondVC
protocol DataDelegate {
func sendData(data : String)
}


class ViewControllerB : UIViewController {


//Declare the delegate property in your SecondVC
var delegate : DataDelegate?
var data : String = "Send data to ViewControllerA."
override func viewDidLoad() {
super.viewDidLoad()
}


@IBAction func btnSendDataPushed(_ sender: UIButton) {
// Call the delegate method from SecondVC
self.delegate?.sendData(data:self.data)
dismiss(animated: true, completion: nil)
}
}

ViewControllerA 确认协议并期望通过委托方法 < strong > sendData 接收数据

    import UIKit
// Conform the  DataDelegate protocol in ViewControllerA
class ViewControllerA : UIViewController , DataDelegate {
@IBOutlet weak var dataLabel: UILabel!


override func viewDidLoad() {
super.viewDidLoad()
}


@IBAction func presentToChild(_ sender: UIButton) {
let childVC =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:"ViewControllerB") as! ViewControllerB
//Registered delegate
childVC.delegate = self
self.present(childVC, animated: true, completion: nil)
}


// Implement the delegate method in ViewControllerA
func sendData(data : String) {
if data != "" {
self.dataLabel.text = data
}
}
}