简体   繁体   English

如何使用委托/协议在多个视图控制器之间传递值

[英]How to Pass Values between Multiple View Controllers using Delegate / Protocol

Basically, I am now intend to use delegate to pass values between view controllers. 基本上,我现在打算使用委托在视图控制器之间传递值。

The flow of the view controllers is A -> B -> C 视图控制器的流是A-> B-> C

When the user does some action in the "C" view controller, how to pass the value back to the first view controller, which is "A"? 当用户在“ C”视图控制器中执行某些操作时,如何将值传递回第一个视图控制器“ A”?

In my own code, the delegate method is never triggerred and "self.delegate" is always "null". 在我自己的代码中,委托方法永远不会触发,并且“ self.delegate”始终为“ null”。 I am not sure why and how to solve this problem. 我不确定为什么以及如何解决这个问题。

Below is the code of the First VC and Third VC: 下面是第一个VC和第三个VC的代码:

#import "ViewController.h"
#import "ThirdViewController.h"

@interface ViewController ()<PassValueProtocal>
@property (weak, nonatomic) IBOutlet UILabel *myLabel;

@end

@implementation ViewController
{
    ThirdViewController *thirdVC;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void) passValueBack:(NSString *)value
{
    NSLog(@"HAHAH");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction)segueToSecondVC:(UIButton *)sender
{
    thirdVC = [ThirdViewController sharedManager];
    thirdVC.delegate = self;
}

@end

#import "ThirdViewController.h"

@interface ThirdViewController ()
@property (weak, nonatomic) IBOutlet UITextField *myTextField;

@end

@implementation ThirdViewController

+ (id) sharedManager
{
    NSLog(@"myDelegate sharedManager");
    static ThirdViewController *sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{ sharedManager = [[self alloc] init]; });
    return sharedManager;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)passValueAction:(UIButton *)sender
{
    NSLog(@"%@", self.delegate);
    if ([self.delegate respondsToSelector:@selector(passValueBack:)])
    {
        [self.delegate passValueBack:self.myTextField.text];
    }
}

The above code doesn't show where you're setting the delegate in your UIViewController . 上面的代码没有显示您在UIViewController哪里设置委托。 That's probably why it's nil and also why your delegate method is never fired. 这可能是为什么它为nil以及为什么永远不会触发您的委托方法的原因。 Set the delegate property after you initialize the UIViewController but before you push it like so: 在初始化UIViewController但在像这样推送它之前设置委托属性:

// Inside your third viewcontroller class:
@interface ThirdViewController ()
@property (weak, nonatomic) id delegate; // make sure the delegate is set to weak
@end


// Maybe in your AppDelegate, before you push the third view controller
ThirdViewController *thirdVC = [[ThirdViewController alloc] init];
thirdVC.delegate = self;
// Now push the VC. The below assumes a UINavigationController but that detail isn't important.
[self.navigationController pushViewController:thirdVC animated:YES];

Yes it's possible to do. 是的,有可能做。 In order to pass data back from C -> A, you need to chain delegates 为了从C-> A传回数据,您需要链接代表

This is how storyboard looks: http://i.imgur.com/9PXdlno.png?1 这是情节提要的外观: http : //i.imgur.com/9PXdlno.png?1

Pay attention segue identifier in storyboard 在情节提要中注意标记标识符

FirstViewController: FirstViewController:

import UIKit

class FirstViewController: UIViewController, SecondViewControllerDelegate {

    @IBAction func buttonPressed(sender: AnyObject) {
        performSegueWithIdentifier("goToSecondView", sender: self)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "goToSecondView"){
            let secondVC: SecondViewController = segue.destinationViewController as! SecondViewController

            secondVC.delegate = self
        }
    }

    func speakSecond(name: String) {
        print("Data from Third view is: \(name)")
    }
}

SecondViewController: SecondViewController:

import UIKit

protocol SecondViewControllerDelegate{
    func speakSecond(name: String)
}


class SecondViewController: UIViewController, ThirdViewControllerDelegate {

    var delegate: SecondViewControllerDelegate?

    @IBAction func buttonPressed(sender: AnyObject) {
        performSegueWithIdentifier("goToThirdView", sender: self)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if(segue.identifier == "goToThirdView"){
            let thirdVC: ThirdViewController = segue.destinationViewController as! ThirdViewController
            thirdVC.delegate = self
        }
    }

    func speakThird(name: String) {
        delegate?.speakSecond(name)
    }
}

ThirdViewController: ThirdViewController:

import UIKit

protocol ThirdViewControllerDelegate{
    func speakThird(name: String)
}

class ThirdViewController: UIViewController {

    var delegate: ThirdViewControllerDelegate?

    @IBOutlet var textField: UITextField!

    @IBAction func buttonPressed(sender: AnyObject) {
        let text = textField.text
        delegate?.speakThird(text)
        self.navigationController?.popToRootViewControllerAnimated(true)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在没有协议的情况下在2个View Controller之间传递值? - How to pass values between 2 View Controllers without protocol? 使用协议和委托在视图控制器之间传递数据 - Passing data between view controllers using protocol and delegate 如何使用委托/协议在 3 个视图之间传递(传递到根视图) - how to use pass between 3 views (pass to the Root view ) using delegate / protocol 如何使用委托将数据从多个视图控制器传递回根视图控制器? IOS 7 - How to pass data back from multiple view controllers to root view controller using delegate? Ios 7 如何使用委托方法在两个视图控制器之间传递对象? - How to use delegate methods to pass objects between two view controllers? 简单的iOS委托协议不适用于在视图控制器之间传递字符串 - Simple iOS Delegate Protocol Not Working With Passing Strings Between View Controllers 使用协议和委托在视图之间传递数据 - using a protocol & delegate to pass data between views 在容器中的同级视图控制器之间使用委托 - Using delegate between sibling view controllers in containers 委托多个视图控制器 - Delegate multiple view controllers 使用委托将数据通过多个视图控制器传回 - Use A delegate to pass data back through multiple view controllers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM