[英]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.