xcode - PerformSegueWithIdentifier 和prepareForSegue

标签 xcode storyboard

我有一个带有 4 个按钮的 UIViewController *vc1。每个按钮都会导致推送到另一个 UIViewController *vc2vc2 显示一些基于按下哪个按钮的信息。我在 vc1prepareForSegue 中将信息从 vc1 传递到 vc2(它只是一个 int 值)。这一切都很好。现在我需要这样做,以便如果 iphone 既在 vc1(vc1 isVisible) 上又在 vc1 上,也将调用 vc2 >vc1 收到 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];
}

现在,如果发生正确的事件,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.

这些错误是在我按下后退按钮后发生的。我添加了 NSLog 语句,这就是为什么我知道 vc2 的 viewDidLoad 每次都会被调用两次。

我使用 Storyboard 为所有 4 个按钮创建了推送序列。我没有给它们贴上标签。我还通过 Storyboard创建了事件推送序列,并为其指定了标识符“已检测到”。我希望这里有人知道我做错了什么。希望得到建议。谢谢。

这是当前代码:

-(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];
}

最佳答案

当 self 是顶 View Controller 时,你绝对应该只调用 PerformSegueWithIdentifier

if (self == self.navigationController.topViewController) {

    ...
}

如果您需要确保只有在您可以执行的操作时才调用某些操作:

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    [self foo];
});

如果您需要在下一个运行循环执行中运行某些内容,您可以执行以下操作:

dispatch_async(dispatch_get_main_queue(), ^{
    [self bar];
});

关于xcode - PerformSegueWithIdentifier 和prepareForSegue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17202534/

相关文章:

ios - 使用 Storyboard在 Controller 之间传递信息(NSInvalidArgumentException)

iOS 在使用 Storyboard 推送 View Controller 时传递数据

iOS Xcode : Editing Root View Controller

ios - 带有 facebook/gmail 的 OAuth 不适用于 iOS 模拟器(Cordova 应用程序 + Firebase)

ios - 从 Objective-C 转换为 Swift (TestFlight)

iphone - 缩放整个 View Controller

xcode - 使用 git 使 Xcode 4 停止自动暂存

objective-c - 通过 url 的 Xcode 6 临时分发

ios - 从 XIB 加载的 UITableViewCell 定义 Storyboard segue

ios - 在 Storyboard 中的 ViewController 之间切换