unwind segue / performSegueWithIdentifier:问题

时间:2013-11-27 18:41:30

标签: ios objective-c xcode

在我的应用中,有一个聊天服务。当用户想要给某人发新消息时,他按下“新聊天”并显示表视图控制器以从朋友列表中进行选择。我正在使用展开segue以返回到前一个视图控制器并在两个视图控制器之间共享数据(主要是数据将是与之聊天的朋友)。 unwind segue完美运行,但是在我的应用程序中,当用户返回主VC时,我会启动一个新的segue,以便直接转到用户聊天的另一个VC;这不起作用。所有segues连接良好,我在每个角落都尝试过NsLog,它正在进入那里甚至是prepareForSegue:正在被访问。我试过放一个NsTimer,认为可能存在一些技术冲突,但它没有用。我将segue更改为聊天VC到模态,现在它给了我这个错误:

  

警告:尝试显示其视图不在窗口层次结构中!

我可以通过其他方式访问此VC,并且它位于层次结构中。我的问题是:可能出现什么问题?放松segues会改变Windows层次结构吗?

照片: enter image description here

更直观地呈现问题,我正在谈论的主要VC是在左下方连接到导航视图控制器。当用户按下新聊天时,会显示右上角的两个VC(一个用于选择朋友或组,另一个用于显示朋友/组)。因此,当从右上角选择一个朋友说VC时,我应该将segue解开到主VC。正如你从主VC看到的还有其他的segues。如果我放松segue就可以工作,如果我正常运作它们就可以工作。

4 个答案:

答案 0 :(得分:14)

它不起作用并且给你错误的原因是因为事情没有按照你认为的顺序发生。

当展开发生时,可见的视图尚未被解除,因此您尝试在视图上执行segue,实际上不在该层次结构中,如错误所示,例如,将NSLog语句放入在最终视图中,然后在主视图控制器中的展开方法中,您可以看到以下内容:

2013-11-27 14:51:10.848 testUnwindProj[2216:70b] Unwind
2013-11-27 14:51:10.849 testUnwindProj[2216:70b] Will Appear
2013-11-27 14:51:11.361 testUnwindProj[2216:70b] View Did Disappear

因此,主视图中的展开被调用,视图将出现(您的主视图控制器),然后您的可见视图被取消。这可能只是一个简单的解决方法:

@interface ViewController () {
    BOOL _unwindExecuted;
}

@end

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"Will Appear");
    if (_unwindExecuted) {
        _unwindExecuted = NO;
        [self performSegueWithIdentifier:@"afterunwind" sender:self];
    }
}

- (IBAction)unwind:(UIStoryboardSegue *)segue
{
    NSLog(@"Unwind");
    _unwindExecuted = YES;
}

答案 1 :(得分:2)

请勿使用计时器或延迟来尝试预测视图何时可能存在。

相反,使用如下调用: - (void)dismissViewControllerAnimated:(BOOL)标志完成:(void(^)(void))完成

当您返回主VC时,完成块会通知您。或者,查看与segue相关的各种调用,以便准确了解何时可以在新窗口上执行操作。

如果所有其他方法都失败了,那么总会有UIViewController viewDidAppear。

答案 2 :(得分:2)

这是处理展开的视图控制器的常见问题,因为在展开期间,该视图控制器可能不在窗口层次结构中。

要解决这个问题,我添加了一个属性segueIdentifierToUnwindTo来协调展开。

这类似于JAManfredi的回答,但扩展它以便能够转向任何视图控制器。

@interface FirstViewController ()
// Use this to coordinate unwind
@property (nonatomic, strong) NSString *segueIdentifierToUnwindTo;
@end

@implementation FirstViewController
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];   
    // Handle unwind
    if (_segueIdentifierToUnwindTo) {
        [self performSegueWithIdentifier:_segueIdentifierToUnwindTo sender:self];
        self.segueIdentifierToUnwindTo = nil;   // reset
        return;
    }
    // Any other code..
}

// Example of an unwind segue "gotoLogin"
- (IBAction)gotoLogin:(UIStoryboardSegue*)sender {
    // Don't perform segue directly here, because in unwind, this view is not in window hierarchy yet!
    // [self performSegueWithIdentifier:@"Login" sender:self];
    self.segueIdentifierToUnwindTo = @"Login";
}
@end

我还分享了如何在我的博客上使用FirstViewController展开的细分:http://samwize.com/2015/04/23/guide-to-using-unwind-segues/

答案 3 :(得分:-2)

好吧解决了这个问题,问题是视图还没有,我不得不推迟这个过程:

[self performSelector:@selector(fireNewConv) withObject:nil afterDelay:1];

然而,有趣的是我尝试延迟NSTimer,但它没有用。