ios 当我再次 popViewController 时,导航无法将值传递给下一个 Viewcontroller

ios Navigation can't pass value to next Viewcontroller when I popViewController again

我有两个ViewController(ViewController,结果ViewController)。

ViewController中有三个按钮,ResultViewController中有一个后退按钮。

在结果中ViewController 我想从 ViewController 传递中获取值。

所以我在 ResultViewController

中添加了下面的代码
 @interface ResultViewController : UIViewController
 - (IBAction)backEvent:(id)sender;
 @property (weak, nonatomic) IBOutlet UILabel *resultLb;
 @property (strong, nonatomic) NSString *selectedVal;
 @end

.m

 - (void)viewDidLoad {
     [super viewDidLoad];
     [self.navigationController setNavigationBarHidden:YES animated:NO];
     self.resultLb.text = self.selectedVal;

 }
 - (IBAction)backEvent:(id)sender {
     [self.navigationController popViewControllerAnimated:NO];
 }

ViewController中有三个按钮动作:

 - (void)viewDidLoad {
     [super viewDidLoad];
     [self.navigationController setNavigationBarHidden:YES animated:NO];
     rvc = [self.storyboard instantiateViewControllerWithIdentifier:@"ResultViewController"];

 }
 - (IBAction)passAEvent:(id)sender {
     rvc.selectedVal = @"A";
     [self.navigationController pushViewController:rvc animated:NO];
 }

 - (IBAction)passBEvent:(id)sender {
     rvc.selectedVal = @"B";
     [self.navigationController pushViewController:rvc animated:NO];
 }

 - (IBAction)passCEvent:(id)sender {
     rvc.selectedVal = @"C";
     [self.navigationController pushViewController:rvc animated:NO];
 }

当我第一次点击按钮 A 时,可以正确地将 "A" 值传递给结果 ViewController。

但是当我点击结果中的后退按钮时ViewController。

然后单击 B 或 C 按钮操作,仍然传递 "A" 值。

我看日志,说不是进入B,C事件。

我再次尝试运行编程,当我用B按钮点击第一个按钮时,输入是正确的,并将"B"值传递给结果ViewController。

但是当我点击后退按钮,然后点击 A 或 C 按钮时,ResultViewController.It 中的值不正确,仍然显示 "B" 值。

不知道为什么?如果不使用delegate或者notify怎么解决?

谢谢。

-----编辑----

致@Gaurav Singh

我找不到关于动画的选项。

这是因为您通过变量 rvc.

保持对 UIViewController 的强引用

您正在视图控制器的 viewDidLoad 方法中设置 resultLb 的值。当您将视图控制器推入堆栈时,您的视图控制器通过获取存储在其变量 selectedVal 中的内容来设置标签。

当您从堆栈中弹出视图控制器时,因为您已将它存储在一个变量中,所以它不会从内存中卸载。它仍然存在。您可能会在点击第二个按钮时再次设置 selectedVal,但是 viewDidLoad 不会再次获得 运行,因为它不会重新实例化。

你可以做的是在 ResultViewController 上重载 setSelectedVal,如下所示:

- (void)setSelectedVal:(NSString *)selectedVal {
    _selectedVal = selectedVal;
    self.resultLb.text = selectedVal;
}

这样,当您从调用视图控制器设置 selectedVal 时,上述方法将是 运行,在 ResultViewController 中设置您的 属性 的值,同时也修改你的标签。

编辑 - 更好

与其在 viewDidLoad: 中设置标签值,不如在 viewWillAppear: 中设置。这样,您就不需要覆盖任何设置器或类似的东西。当 viewWillAppear 被调用时,它会读取您设置的字符串并相应地设置标签的文本。

希望对您有所帮助!

你只是让它变得复杂。我会这样做:

  1. 首先,我将创建一个从 ViewController 到 Result Controller(View Controller 到 View Controller segue)的故事板 segue,并为该 segue 分配一个合适的标识符(比如 "resultSegue" )

  2. 那么下面的代码就可以工作了

    - (IBAction)passAEvent:(id)sender {
        [self performSegueWithIdentifier:@"resultSegue" sender:@"A"];
    }
    
    - (IBAction)passBEvent:(id)sender {
        [self performSegueWithIdentifier:@"resultSegue" sender:@"B"];
    }
    
    - (IBAction)passCEvent:(id)sender {
        [self performSegueWithIdentifier:@"resultSegue" sender:@"C"];
    }
    
    - (void)prepareForSegue:(UIStoryboardSegue *)segue
             sender:(id)sender {
          if([segue.identifier isEqualToString:@"resultSegue"]){
              ResultViewController *rvc = segue.destinationViewController;
              rvc.selectedVal = sender; //Here SENDER will have value: A,B or C which we have passed in performSegueWithIdentifier:sender: method
          }
    }
    

编辑: prepareForSegue:sender 中的代码:已修改方法,以便在处理目标之前检查 segue 标识符ViewController

rvc = [self.storyboard instantiateViewControllerWithIdentifier:@"ResultViewController"];

viewWillAppear

首先,你应该给segue一个"id",比如"resultSegue"。 然后,使用代码:

- (void)prepareForSegue:(UIStoryboardSegue *)segue
     sender:(id)sender
{
     if([segue.identifier isEqualToString:@"resultSegue"]){
      ResultViewController *rvc = segue.destinationViewController;
      rvc.selectedVal.text = someUILabel.text;
than use the  [self.navigationController pushViewController:rvc animated:NO];//.........
}

如果你不解决问题,我在家的时候会告诉你更多的细节...... 谢谢!