Вход из ViewController в SplitViewController - PullRequest
2 голосов
/ 19 декабря 2011

Я пишу небольшое приложение для использования результатов веб-службы.Результаты представлены в 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 для переключения на 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];}

Пока все работает, но теперь у меня есть кнопка выхода из системы в PopoverView на detailViewControllerмоего SplitView, который следует за экраном входа в систему.Я думал, что смогу сделать то же самое, поэтому я сделал:

- (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: разрешеноArrowDirections: 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.windowsetRootViewController: CVC];

Ответы [ 2 ]

1 голос
/ 12 января 2013

Я реализовал то же самое, используя пользовательский переход.Кажется, это сработало и намного проще.

@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
0 голосов
/ 10 октября 2016

Для тех, кто ищет похожие ответы:

Я использовал свойство UISplitViewController .preferredDisplayMode для создания этого же рабочего процесса: экран входа в систему для разделения главного экрана таблицы. Вид слева, подробно вид справа.

FWIW, я встроил навигационные контроллеры как SplitViewController 'Master' и 'Detail', а приложение поддерживает только альбомную ориентацию.

При запуске приложения Master View (слева) - это любой ViewController, который вы хотите отобразить слева после входа в систему. Подробный вид (справа) - это экран входа в систему. В логин ViewController viewWillAppear добавить (Swift)

self.splitScreenController?.preferredDisplayMode = .primaryHidden

При этом экран входа в систему будет представлен как один экран, а не как разделенный экран. После успешного входа в систему представьте контроллер подробного представления, который вы хотите отобразить. В prepareForSegue из входа в VC или viewDidLoad DetailVC вызовите

self.splitScreenController?.preferredDisplayMode = .automatic

чтобы отобразить обычный разделенный экран Master / Detail. Или,

self.splitScreenController?.preferredDisplayMode = .allVisible

, чтобы разделить экран в портретном режиме.

При выходе пользователя из системы я вызываю popToRootViewController на обоих контроллерах nav для возврата обратно в режим просмотра.

Легко, не мешайте с окнами и не сбрасывайте корневые представления.

...