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
被调用时,它会读取您设置的字符串并相应地设置标签的文本。
希望对您有所帮助!
你只是让它变得复杂。我会这样做:
首先,我将创建一个从 ViewController 到 Result Controller(View Controller 到 View Controller segue)的故事板 segue,并为该 segue 分配一个合适的标识符(比如 "resultSegue" )
那么下面的代码就可以工作了
- (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];//.........
}
如果你不解决问题,我在家的时候会告诉你更多的细节......
谢谢!
我有两个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
.
您正在视图控制器的 viewDidLoad
方法中设置 resultLb
的值。当您将视图控制器推入堆栈时,您的视图控制器通过获取存储在其变量 selectedVal
中的内容来设置标签。
当您从堆栈中弹出视图控制器时,因为您已将它存储在一个变量中,所以它不会从内存中卸载。它仍然存在。您可能会在点击第二个按钮时再次设置 selectedVal
,但是 viewDidLoad
不会再次获得 运行,因为它不会重新实例化。
你可以做的是在 ResultViewController
上重载 setSelectedVal
,如下所示:
- (void)setSelectedVal:(NSString *)selectedVal {
_selectedVal = selectedVal;
self.resultLb.text = selectedVal;
}
这样,当您从调用视图控制器设置 selectedVal
时,上述方法将是 运行,在 ResultViewController
中设置您的 属性 的值,同时也修改你的标签。
编辑 - 更好:
与其在 viewDidLoad:
中设置标签值,不如在 viewWillAppear:
中设置。这样,您就不需要覆盖任何设置器或类似的东西。当 viewWillAppear
被调用时,它会读取您设置的字符串并相应地设置标签的文本。
希望对您有所帮助!
你只是让它变得复杂。我会这样做:
首先,我将创建一个从 ViewController 到 Result Controller(View Controller 到 View Controller segue)的故事板 segue,并为该 segue 分配一个合适的标识符(比如 "resultSegue" )
那么下面的代码就可以工作了
- (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];//.........
}
如果你不解决问题,我在家的时候会告诉你更多的细节...... 谢谢!