xcode performSegueWithIdentifier 和 prepareForSegue
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17202534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
performSegueWithIdentifier and prepareForSegue
提问by MichelleJS
I have a UIViewController *vc1
with 4 buttons. Each button causes a push segue to another UIViewController *vc2
. vc2
is shows some information based on which button was pushed. I pass the infomation from vc1
to vc2
in vc1
's prepareForSegue
(its just an int value). This all works fine. Now I need to make it so that the vc2
will also be called if the iphone is both on vc1
(vc1
isVisible) and a vc1
receives a UINotification
(something happens with a bluetooth device). Here is my code:
我有一个UIViewController *vc1
带 4 个按钮的。每个按钮都会导致一个 push segue 到另一个UIViewController *vc2
。vc2
是根据按下的按钮显示一些信息。我通过信息来源从vc1
到vc2
在vc1
的prepareForSegue
(它只是一个int值)。这一切正常。现在我需要这样做,以便vc2
在 iphone 处于开启状态vc1
(vc1
isVisible)和vc1
接收 a UINotification
(蓝牙设备发生某些事情)时也会调用。这是我的代码:
-(void) eventDetected:(NSNotification *)notification{
if(self.isViewLoaded && self.view.window){
[self performSegueWithIdentifier:@"detected" sender:self];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
VC2 *destination = [segue destinationViewController];
[destination setValue:value];
}
Right now if the proper event happens vc2
loads twice, instead of once. And I get these error messages in the output logs:
现在,如果正确的事件发生vc2
加载两次,而不是一次。我在输出日志中收到这些错误消息:
"Nested push animation can result in corrupted navigation bar" & "Unbalanced calls to begin/end appearance transitions for .corrupted. & "Finishing up a navigaion transition in an unexpected state. Navigation Bar subview tree might get corrupted.
“嵌套推送动画可能会导致导航栏损坏”和“对 .corrupted 的开始/结束外观转换的调用不平衡。”和“在意外状态下完成导航转换。导航栏子视图树可能会损坏。
These errors happen after I press the back button. I added NSLog
statements which is why I know that vc2
's viewDidLoad
is getting called twice every time.
我按下后退按钮后会发生这些错误。我添加了NSLog
语句,这就是为什么我知道vc2
'sviewDidLoad
每次都会被调用两次。
I created the push segues for all 4 buttons using the storyboard. I have not labelled them. I created the event push segue through the storyboard as well and gave it the identifier "detected"
. I hope someone on here has some idea about what I am doing wrong. Would appreciate advice. Thanks.
我使用故事板为所有 4 个按钮创建了 push segues。我没有给它们贴上标签。我也通过情节提要创建了事件推送segue,并给了它 identifier "detected"
。我希望这里有人对我做错了什么有一些想法。将不胜感激的建议。谢谢。
Here is the current code:
这是当前的代码:
-(void)viewDidAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exerciseDetected:) name:@"ExerciseDetected" object:nil];
[[NSNotifcationCenter defaultCenter] addObserver:self selector:@selector(cancelExercise:) name@"cancelExercise" object:nil];
}
-(void)exerciseDetected:(NSNotification *)notification{
if(self.isViewLoaded && self.view.window){
if(self == self.navigationController.topViewController){
if(!timerRunning){
timerRunning =YES;
_exerciseTimer = (NSTimer scheduledTimerWithTimeInterval:EXERCISE_AUTOSTART_TIME target:self selector:@selector(startExercise:) userInfo:nil repeats:NO];
}
}
}
}
-(void)cancelExercise:(id)sender{
[_exerciseTimer invalidate];
timerRunning = NO;
}
-(void) startExercise: (id)sender{
timerRunning = NO;
[self performSegueWithIdentifier:@"detected" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
vc2 *destination = [segue destinationViewController];
[destination setSElectedExerciseIDFromMenu:_selectedExercise];
}
回答by GayleDDS
You should definitely only call performSegueWithIdentifier when self is the top view controller
当 self 是顶视图控制器时,你绝对应该只调用 performSegueWithIdentifier
if (self == self.navigationController.topViewController) {
...
}
If you need to be sure something is only called once you can do:
如果您需要确保某事只被调用一次,您可以执行以下操作:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self foo];
});
If you need to run something in the next run loop execution you can do:
如果您需要在下一个运行循环执行中运行某些内容,您可以执行以下操作:
dispatch_async(dispatch_get_main_queue(), ^{
[self bar];
});