Подтвердить что ты не робот

UIViewControllerHierarchyInconsistency

Я пытаюсь создать свое приложение, и в какой-то момент я нажимаю UIViewController, а затем получаю эту ошибку. Я не совсем уверен, почему.

'UIViewControllerHierarchyInconsistency', причина: 'Вид может быть только связанных с не более чем одним контроллером представления за раз! View > . Удалите эту связь, прежде чем связывать это представление с.

PageViewController *viewController;

viewController = [[PageViewController alloc] initWithManagedObjectContext:managedObjectContext];
dataSource = [[PagesDataSource alloc] initWithManagedObjectContext:managedObjectContext];

PVPage *selectedPage = [[dataSource pages] objectAtIndex:itemIndex];
[viewController setRepresentedPage:selectedPage];

PageFlipperAppDelegate *appDelegate = (PageFlipperAppDelegate *)[[UIApplication sharedApplication] delegate];
[(UINavigationController *)[[appDelegate window] rootViewController] setToolbarHidden:YES animated:YES];
[(UINavigationController *)[[appDelegate window] rootViewController] pushViewController:viewController animated:YES];

В моем pageViewController...................

- (id)initWithManagedObjectContext:(NSManagedObjectContext *)initManagedObjectContext
{
    if ((self = [super initWithNibName:@"PageView" bundle:nil]))
    {
        [self setManagedObjectContext:initManagedObjectContext];
        dataSource = [[PagesDataSource alloc] initWithManagedObjectContext:[self managedObjectContext]];
    }
    return self;
}
4b9b3361

Ответ 1

У меня возникла такая же ошибка, когда я хотел, чтобы представление прокрутки настроек отображалось в popover.

Вот мой оригинальный код с комментариями о том, что я изменил, чтобы его решить:

SettingsViewController *settingsViewController;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];    
settingsViewController = [storyboard instantiateViewControllerWithIdentifier:@"Settings"];

CGRect contentRect = CGRectMake(10, 10, 320, 700);

// This entire object got deleted in the fixed version
UIViewController *popoverContent = [[UIViewController alloc] init];
popoverContent.view = settingsViewController.view;
popoverContent.contentSizeForViewInPopover = contentRect.size;

// Instead of popoverContent I just put the settingsViewController in directly.
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];

[popoverController presentPopoverFromRect:[sender frame]
                                   inView:(UIButton*)sender
                 permittedArrowDirections:UIPopoverArrowDirectionLeft
                                 animated:YES];

Линия popoverContent.view = settingsViewController.view является тем, что вызывало крах (без этого мой popover был пуст, конечно). С точки зрения ошибки UIViewControllerHierarchyInconsistency имеет смысл, что я не должен был переназначать ее, а затем добавлять ее в другой контроллер представления.

В вашем случае я предполагаю, что что-то подобное происходит в pushViewController или в другом месте вашего кода. Может ли это быть вообще?

Ответ 2

Сценарий Gotcha: если у вас есть два UIViewControllers в том же файле .XIB с точками просмотра, указывающими на один и тот же вид, вы будете поднимать исключение UIViewControllerHierarchyInconsistency при загрузке nib, например, вызывая свойство .view на одном из просматривать контроллеры.

Ответ 3

Просто чтобы добавить ответы Matt и owenfi, в общих чертах (или, по крайней мере, то, что я видел до сих пор) это происходит, когда вы создаете пользовательский XIB для UIViewController, а в Interface Builder вы добавляете как View Controller и View, где ваш объект представления является подзором вашего контроллера просмотра.

Это приведет к тому, что розетка представления будет установлена ​​как на UIViewController, которое у вас есть в IB, так и на класс, установленный как владелец файла, поэтому исключение UIViewControllerHierarchyInconsistency.

Смотрите этот ответ для некоторых скриншотов, объясняющих проблему.

Ответ 4

У меня была такая же проблема для элементов управления popover после перехода на iOS 6. Однако моя реализация немного отличалась от ответов здесь. Итак, я хотел бы поделиться своим решением:

У меня есть представление в xib, но оно отображается в другом месте с разными данными на экране во всплывающем представлении. Когда я показываю представление, я создаю UIViewController и назначаю свое представление как представление контроллера. Он работает в первый раз, но когда я пытаюсь показать его во второй раз, он выходит из строя с UIViewControllerHierarchyInconsistency. Итак, я определил глобальный UIViewController один раз, как показано в приведенном ниже коде.

сбои:

-(void) showInTrainWindow:(int)trainLegId onView:(UIView *)view
{
    //update labels on vwTrain for trainLegId
    [self prepareInTrainProperties:trainLegId];
    UIViewController* popoverContent = [[UIViewController alloc] init];
    popoverContent.view = vwInTrain; //IT WAS CRASHING ON THIS LINE    
    popoverContent.contentSizeForViewInPopover = CGSizeMake(vwInTrain.frame.size.width, vwInTrain.frame.size.height);
    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
    self.popoverController.delegate = self;    
    [self.popoverController presentPopoverFromRect:CGRectMake(325, view.frame.origin.y - scrollViewTimeLine.contentOffset.y + 65, 1, 1)
                                            inView:vwTimeLine
                          permittedArrowDirections:UIPopoverArrowDirectionLeft
                                          animated:YES];
    [popoverContent release];
}

Fixed

-(void) showInTrainWindow:(int)trainLegId onView:(UIView *)view
{
    //update labels on vwTrain for trainLegId
    [self prepareInTrainProperties:trainLegId];
    if ( self.popoverContentInTrain == nil )
    {
        self.popoverContentInTrain = [[UIViewController alloc] init];
        self.popoverContentInTrain.view = vwInTrain;
        self.popoverContentInTrain.contentSizeForViewInPopover = CGSizeMake(vwInTrain.frame.size.width, vwInTrain.frame.size.height);
    }
    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:self.popoverContentInTrain];
    self.popoverController.delegate = self;    
    [self.popoverController presentPopoverFromRect:CGRectMake(325, view.frame.origin.y - scrollViewTimeLine.contentOffset.y + 65, 1, 1)
                                            inView:vwTimeLine
                          permittedArrowDirections:UIPopoverArrowDirectionLeft
                                          animated:YES];
}

Ответ 5

Эта ошибка также возникнет, если вы не выполните следующие рекомендации: Создание настраиваемых контроллеров Просмотр содержимого

В принципе, вам нужно позвонить:

[yourVC removeFromParentViewController];

если вы

[parentVC addChildViewController: yourVC];

Эта ошибка часто может быть сопряжена с чем-то вроде "активного контроллера представления"

Ответ 6

Одна из причин, по которой я застрял, заключалась в том, что я скопировал ViewController из файла storyboard в xib, который будет загружен программно для моей потребности. Но в xib я должен действительно скопировать вид не весь контроллер представления. И установите file owner в свой пользовательский контроллер представлений. Это решает мою аналогичную проблему с ошибкой.