2

我正在编写一个小应用程序来使用网络服务的结果。结果显示在 SplitViewController 中,左侧是结果,右侧是详细信息。在获得结果之前,我要求用户通过登录屏幕登录,该屏幕首先出现在应用程序启动时。

登录成功后,我通过更改应用程序的 RootViewController 来管理登录过程:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

if([[segue identifier] isEqualToString:@"LoginControllerSeque"] && [self doLogin]){
    TMAppDelegate *appDelegate = (TMAppDelegate *)[[UIApplication sharedApplication]delegate];
    // IPad 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)  {
        UISplitViewController *cvc = (UISplitViewController *)[segue destinationViewController];
        [appDelegate.window setRootViewController:cvc];  
    } 
    // Other device
    else {
        UINavigationController *cvc = (UINavigationController *)[segue destinationViewController];
        [appDelegate.window setRootViewController:cvc];  
    }  
    [appDelegate switchToMainView];
}
else{
    alertView = [[UIAlertView alloc] initWithTitle:@"access denied" message:@"access denied" delegate:self cancelButtonTitle:@"back" otherButtonTitles:nil];
    [alertView show];
}

我正在使用 Storyboard segue 切换到 SplitViewController,但如果没有进一步的操作,它不会做任何事情。

在我的 AppDelegate 中有以下部分:

- (void)switchToMainView{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
    UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
    splitViewController.delegate = (id)navigationController.topViewController;

    UINavigationController *masterNavigationController = [splitViewController.viewControllers objectAtIndex:0];
    TMMasterViewController *controller = (TMMasterViewController *)masterNavigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
} else {
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    TMMasterViewController *controller = (TMMasterViewController *)navigationController.topViewController;
    controller.managedObjectContext = self.managedObjectContext;
}  

[self.window reloadInputViews]; 
[self.window makeKeyAndVisible];}

到目前为止,一切正常,但现在我的 SplitView 的 detailViewController 上的 PopoverView 中有一个注销按钮,该按钮位于登录屏幕之后。我想我可以这样做,所以我做了:

- (IBAction)logout:(id)sender {
[self.currentPopover dismissPopoverAnimated:NO];
TMAppDelegate *appDelegate = (TMAppDelegate *)[[UIApplication sharedApplication]delegate];
[appDelegate.window setRootViewController:[appDelegate loginViewController]];  
[appDelegate switchToLoginView];
}

在 AppDelegate 中:

- (void)switchToLoginView
{
[self.window reloadInputViews]; 
[self.window makeKeyAndVisible];
}

现在,如果我第二次尝试登录,我得到一个错误:原因:'-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]:无法从没有窗口的视图中呈现弹出框。'

我不知道为什么这是第一次工作,第二次我遇到这些问题。

任何人都可以帮助我或给我一个提示吗?也许这是处理登录的错误概念?

更新:

问题恰好出现在这部分:

  // Beim IPad müssen wir uns anders verhalten als beim Phone
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) 
    {
        UISplitViewController *cvc = (UISplitViewController *)[segue destinationViewController];
        [appDelegate.window setRootViewController:cvc];  
    } 

通过步入行: [appDelegate.window setRootViewController:cvc];

4

2 回答 2

1

我使用自定义 segue 实现了相同的功能。这似乎已经奏效并且简单得多。

@implementation LoginSegue
- (void) perform {
    NSLog(@"Do the segue you way");
    UIViewController *src = self.sourceViewController;
    UIWindow *window = src.view.window;
    [window addSubview:[self.destinationViewController view]];
    window.rootViewController = self.destinationViewController;
}
@end
于 2013-01-11T22:07:09.257 回答
0

对于任何寻找类似答案的人:

我使用该UISplitViewController .preferredDisplayMode属性创建了相同的工作流程:登录屏幕到左侧的分屏主 tableView,右侧的 detailView。

FWIW,我将导航控制器嵌入为 SplitViewController 的“Master”和“Detail”,并且应用程序仅支持横向。

在应用程序启动时,主视图(左侧)是您登录后想要在左侧显示的任何 ViewController。详细视图(右)是登录屏幕。在登录 ViewController 中viewWillAppear添加(Swift)

self.splitScreenController?.preferredDisplayMode = .primaryHidden

这会将登录屏幕显示为单个屏幕视图,而不是分屏。成功登录后,显示您要显示的详细视图控制器。在prepareForSegue登录 VC 或viewDidLoadDetailVC 中,调用

self.splitScreenController?.preferredDisplayMode = .automatic

显示常规的主/详细分屏。或者,

self.splitScreenController?.preferredDisplayMode = .allVisible

强制分屏显示纵向。

在用户注销时,我会调用popToRootViewController两个导航控制器以重置为登录视图。

简单,不会弄乱窗口或重置根视图。

于 2016-10-10T19:05:58.400 回答