2015-07-28 7 views
2

В принципе, теперь я намерен использовать делегат для передачи значений между контроллерами представлений.Как передать значения между контроллерами множественного представления, используя делегат/протокол

Поток контроллеров зрения А -> В -> С

Когда пользователь делает какое-либо действие в представлении контроллера «C», как передать значение обратно в первый контроллер представления, которое является «А»?

В моем собственном коде метод делегата никогда не запускается, а «self.delegate» всегда «null». Я не уверен, почему и как решить эту проблему.

Ниже приведен код первых ОК и третьего ВК:

#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]; 
    } 
} 
+0

Посмотрите на http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers?rq=1 – JaredH

+0

вы считаете ли используя разматывать segues? – Yariv

ответ

0

Приведенные выше код не показывает, где вы устанавливаете делегат в вашем UIViewController. Вероятно, поэтому это нуль, а также почему ваш метод делегата никогда не запускается. Установите свойство делегата после инициализации 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]; 
+0

Но я не хочу напрямую обращаться к третьему VC, я просто хочу, чтобы пользователь изменил некоторые действия в третьем VC, и после этого, когда пользователь вернется к первому VC, он может увидеть изменения, вызванные третьим VC –

+0

Право, но вы говорили, что делегат всегда ноль. Это потому, что вы не устанавливаете его перед созданием VC. – JaredH

+0

Ох ~~~ Я просто забыл скопировать файл .h из третьего VC, я установил его в файле .h третьего VC: –

0

Да, это возможно сделать. Для того, чтобы передать данные от C -> A, вам необходимо цепными делегатов

Это как раскадровки выглядит: http://i.imgur.com/9PXdlno.png?1

Обратите внимание Segue идентификатор в раскадровке

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

} 
Смежные вопросы