【问题标题】:Manual segue not transitioning properly手动转场没有正确过渡
【发布时间】:2013-05-22 20:50:48
【问题描述】:

我对 ios 有点陌生,但我已经能够糊涂了……直到现在。我有一个带有登录页面的应用程序。我做的第一件事是创建一些空视图控制器并将它们粘贴在故事板上。我有一个 LoginViewController,其中包含一些用于 userId 和密码的文本字段以及一个登录按钮。计划是,如果您成功登录,您将被带到 TabViewController。现在这是开箱即用的。我删除了用它创建的两个视图控制器,并用两个 NavigationController 替换了它们。

只是为了测试我从登录按钮到 TabViewController 的所有内容。一切正常。意见出现了。所有开箱即用的东西都有效。

下一步我尝试模拟实际登录。由于我必须通过 Web 服务调用来执行此操作,因此我认为它需要是异步的。我删除了为登录按钮添加的初始 segue,并将按钮中的 IBAction 添加到了我的 LoginViewController。我还在我的 LoginViewController 中添加了一个手动 segue 到 TabViewController,并将其命名为“loginSegue”

这是我目前的代码:

- (IBAction)login:(id)sender {
[Decorator showViewBusyIn:self.aView
            scale:1.5
        makeWhite:NO];

self.clientIdText.enabled = NO;
self.userIdText.enabled = NO;
self.passwordText.enabled = NO;
UIButton* loginBtn = sender;

loginBtn.enabled = NO;
[Decorator showViewBusyIn:self.aView
             scale:2.0
         makeWhite:NO];

self.operation = [[NSInvocationOperation alloc]
            initWithTarget:self
                  selector:@selector(doLogin)
                object:nil];
self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperation:self.operation];
}

-(void)doLogin{
    [NSThread sleepForTimeInterval:1];
    [Decorator removeBusyIndicatorFrom:self.aView];
// this is where I will eventually put the login code...
    [self performSegueWithIdentifier:@"loginSegue" sender:self];
}

我调用 sleepForTimeInterval 来模拟等待 Web 服务调用完成。我稍后会删除它。装饰器的东西只是显示和删除一个活动指示器视图。

当我执行所有这些操作时,segue 可以正常工作,但与登录视图控制器关联的视图仍保留在屏幕上。换句话说,TabViewController 出现了。第一个项目被选中。 NavigationController 出现了,但与之关联的 VC 和它包含的视图没有出现。 LoginViewController 的视图保留在那里。

由于当我将 segue 放在登录按钮上时所有导航都正常工作,所以我认为它与调用操作有关。无论是那个还是我的视图或视图控制器层次结构都搞砸了。

关于我做错了什么有什么想法吗? 这是登录的好方法吗?

非常感谢任何帮助, 纳特

【问题讨论】:

  • 我真的不明白为什么,但问题似乎是我从主线程以外的线程调用 performSegueWithIdentifier:sender: 。如果我强制调用在主线程上发生,我的 segue 工作正常。我用以下内容替换了对 performSegueWithIdentifier:sender 的调用: [self performSelectorOnMainThread:@selector(exeOnMainThread:) withObject:self waitUntilDone:NO]; exeOnMainThread 只是调用 performSegueWithIdentifer:sender: 所以我让它工作了,但我仍然想知道这是否是一种登录的好方法。

标签: ipad storyboard


【解决方案1】:

对于这种操作,使用 GCD 会更容易。你会做这样的事情:

- (void)doLogin
{
    dispatch_queue_t loginQueue = dispatch_queue_create(“login”, NULL);
    dispatch_async(loginQueue, ^{         
        // this is where you will eventually put the login code...
        dispatch_async(dispatch_get_main_queue(), ^{
            [Decorator removeBusyIndicatorFrom:self.aView];
            [self performSegueWithIdentifier:@"loginSegue" sender:self];
        });
    }); 
}

在您的-(IBAction)login:(id)sender 中,您只需调用[self doLogin] 而不是

self.operation = [[NSInvocationOperation alloc]
                                  initWithTarget:self
                                        selector:@selector(doLogin)
                                          object:nil];
self.queue = [[NSOperationQueue alloc] init];
[self.queue addOperation:self.operation];

查看这个question,它简要解释了 GCD 和 NSOperationQueue 之间的主要区别是什么

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    相关资源
    最近更新 更多