繁体   English   中英

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

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

基本上,我现在打算使用委托在视图控制器之间传递值。

视图控制器的流是A-> B-> C

当用户在“ C”视图控制器中执行某些操作时,如何将值传递回第一个视图控制器“ A”?

在我自己的代码中,委托方法永远不会触发,并且“ self.delegate”始终为“ null”。 我不确定为什么以及如何解决这个问题。

下面是第一个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];
    }
}

上面的代码没有显示您在UIViewController哪里设置委托。 这可能是为什么它为nil以及为什么永远不会触发您的委托方法的原因。 在初始化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];

是的,有可能做。 为了从C-> A传回数据,您需要链接代表

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

在情节提要中注意标记标识符

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:

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:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM