17

アプリをビルドしようとしていますが、ある時点で UIViewController をプッシュすると、このエラーが発生します。正確な理由はわかりません。

'UIViewControllerHierarchyInconsistency', reason: 'ビューは、一度に 1 つのビュー コントローラーにのみ関連付けることができます! ビュー > は に関連付けられています。このビューを に関連付ける前に、この関連付けをクリアしてください。'

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;
}
4

6 に答える 6

12

問題のあるシナリオ: ビュー アウトレットが同じビューを指す同じ .XIB ファイルに 2 つの UIViewController がある場合、ビュー コントローラーの 1 つで .view プロパティを呼び出すなどして、nib が読み込まれると、UIViewControllerHierarchyInconsistency 例外が発生します。

于 2012-09-21T01:18:52.197 に答える
4

Mattとowenfiの答えに追加するだけで、一般的な行(または少なくともこれまでに見たもの)では、これはaのカスタムXIBを作成し、InterfaceBuilderでViewControllerとViewオブジェクトのあるViewの両方UIViewControllerを追加するときに発生します。 ViewControllerのサブビューです。

これにより、ビューのアウトレットがUIViewControllerIBにあるユーザーと、ファイルの所有者として設定されているクラスの両方に設定されるため、UIViewControllerHierarchyInconsistency例外が発生します。

問題を説明するスクリーンショットについては、この回答を参照してください。

于 2012-10-03T14:29:50.133 に答える
3

iOS 6 に移行した後、ポップオーバー コントロールで同じ問題が発生していました。だから、私は私の解決策を共有したいと思います:

xib にビューがありますが、別の場所に表示され、画面上の別のデータがポップアップ ビューに表示されます。ビューを表示するときは、UIViewController を作成し、ビューをコントローラーのビューとして割り当てます。最初は機能しますが、2 回目に表示しようとすると、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];
}

修理済み:

-(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];
}
于 2012-10-18T14:27:43.643 に答える
2

このエラーは、次のガイドラインに従わない場合にも発生します:カスタム コンテンツ ビュー コントローラーの作成

基本的に、次のように呼び出す必要があります。

[yourVC removeFromParentViewController];

あなたが持っている場合

[parentVC addChildViewController:yourVC];

このエラーは、多くの場合、「アクティブ ビュー コントローラー」に関するものと対になっている可能性があります。

于 2013-03-14T23:30:41.473 に答える
1

設定スクロール ビューをポップオーバーに表示したいときに、同じエラーが発生しました。

これを解決するために変更した内容についてのコメントを含む元のコードを次に示します。

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がクラッシュの原因でした (それがなければ、もちろんポップオーバーは空でした)。UIViewControllerHierarchyInconsistency エラーの観点からは、それを再割り当てしてから別のビュー コントローラーに追加するべきではなかったことが理にかなっています。

あなたの場合、pushViewController またはコードの他の場所で同様のことが起こっていると思います。まったくそうでしょうか?

于 2012-08-12T00:04:52.600 に答える
0

私が固執した理由の 1 つは、必要に応じてプログラムでロードされるようにファイルからファイルにコピーしViewControllerたことです。しかし、xib では、ビュー コントローラー全体ではなくビューを実際にコピーする必要があります。そして、カスタム ビュー コントローラーに設定します。それは私の同様のエラー問題を解決します。storyboardxibfile owner

于 2017-06-06T10:29:44.570 に答える