web-dev-qa-db-ja.com

UIViewControllerビューをサブビューとして追加する方法

Google社員への注意、このQ-Aは6年前!です!

以下のMickyや他の人が言及しているように、これはiOSでContainersを使用して日常的に行われています。


多くのサブビューを制御するViewControllerがあります。ボタンの1つをクリックすると、別のViewControllerを初期化し、そのビューをこのビューのサブビューとして表示します。ただし、サブビューはサブビューのフレームの境界を超えており、画面全体をインファクトで埋めています。

何が間違っているのでしょうか?この問題は、UIViewControllerのビューにフレーム(0,0,320,460)があり、画面全体に表示されるためだと推測しています(ただし、サブビューフレームの境界内でタッチされた場合のみタッチイベントを受け取ります)。サブビューとして収まるようにフレームのサイズを変更するにはどうすればよいですか。

要するに、ViewControllerのビューをサブビューとして別のViewControllerのビューに追加するのに助けが必要です。

ありがとう!

75
sperumal

iOS 5以降 、Appleでは、 カスタムコンテナ を追加して、UIViewControllerから別のUIViewController特に addChildViewController などのメソッドを介してネストするUIViewControllers

EDIT:リンク破損を回避するためにインプレースサマリーを含める

私は引用する:

iOSには、アプリの整理に役立つ多くの標準コンテナが用意されています。ただし、場合によっては、どのシステムコンテナーによって提供されるものとも一致しないカスタムワークフローを作成する必要があります。おそらくあなたのビジョンでは、アプリには、特殊なナビゲーションジェスチャまたはアニメーションの遷移を伴う特定の組織子View Controllerが必要です。 それを行うには、カスタムコンテナを実装します- 詳細を教えてください...

...そして:

コンテナを設計するとき、コンテナ、親、および他のView Controller、その子の間に明示的な親子関係を作成します- 詳細を教えてください

サンプル(Apple docs)の提供)別のView Controllerのビューをコンテナのビュー階層に追加する

- (void) displayContentController: (UIViewController*) content
{
   [self addChildViewController:content];                 
   content.view.frame = [self frameForContentController]; 
   [self.view addSubview:self.currentClientView];
   [content didMoveToParentViewController:self];          
}

乾杯、

ミッキー・ダンカン

86
MickyD

この連中のおかげで私はやった http://highoncoding.com/Articles/848_Creating_iPad_Dashboard_Using_UIViewController_Containment.aspx

UIViewを追加し、ヘッダーに接続します。

@property (weak, nonatomic) IBOutlet UIView *addViewToAddPlot;

In-(void)viewDidLoadこれを行います:

ViewControllerToAdd *nonSystemsController = [[ViewControllerToAdd alloc] initWithNibName:@"ViewControllerToAdd" bundle:nil];
    nonSystemsController.view.frame = self.addViewToAddPlot.bounds;
    [self.addViewToAddPlot addSubview:nonSystemsController.view];
    [self addChildViewController:nonSystemsController];
    [nonSystemsController didMoveToParentViewController:self];

楽しい

41
Naloiko Eugene

この回答はiOSの古いバージョンでは正しいですが、現在は廃止されています。カスタムコンテナをカバーするMicky Duncanの回答を使用する必要があります。

これをしないでください! UIViewControllerの目的は、画面全体を駆動することです。これは単に適切ではなく、必要なものは何も追加しません。

必要なのは、カスタムビューを所有するオブジェクトだけです。 UIView自体のサブクラスを使用するだけで、ウィンドウ階層に追加でき、メモリ管理は完全に自動化されます。

サブビューNIBの所有者にUIViewのカスタムサブクラスを指定します。 contentViewアウトレットをこのカスタムサブクラスに追加し、nib内のビューに向けます。カスタムサブクラスで、次のようなことを行います。

- (id)initWithFrame: (CGRect)inFrame;
{
    if ( (self = [super initWithFrame: inFrame]) ) {
        [[NSBundle mainBundle] loadNibNamed: @"NibNameHere"
                                      owner: self
                                    options: nil];
        contentView.size = inFrame.size;
        // do extra loading here
        [self addSubview: contentView];
    }
    return self;
}

- (void)dealloc;
{
    self.contentView = nil;
    // additional release here
    [super dealloc];
}

(ここでは、initWithFrame:を使用してサブビューを構築していると想定しています。)

26
Steven Fisher

これらの答えはすべて不完全であると思うので、viewControllerのビューを別のviewControllerのビューのサブビューとして追加する適切な方法を次に示します。

    [self addChildViewController:viewControllerToAdd];
    [self.view addSubview:viewControllerToAdd.view];
    [viewControllerToAdd didMoveToParentViewController:self];

必要に応じて、これをスニペットとしてコードにコピーできます。 SOはコード置換のフォーマットを理解していないようですが、Xcodeではきれいに表示されます。

    [self addChildViewController:<#viewControllerToAdd#>];
    [self.view addSubview:<#viewControllerToAdd#>.view];
    [<#viewControllerToAdd#> didMoveToParentViewController:self];

willMove はaddChildで自動的に呼び出されます。ありがとう@iOSSergey

カスタムコンテナがaddChildViewController:メソッドを呼び出すと、View ControllerのwillMoveToParentViewController:メソッドが自動的に呼び出され、追加する前に子として追加されます。

17
Logan

つかいます:

[self.view addSubview:obj.view];
6
rahul gupta

viewcontroller.view.frameのフレームサイズを変更し、サブビューに追加します。 [viewcontrollerparent.view addSubview:viewcontroller.view]

1
CiNN

UIViewControllerをサブビューとして表示するSDKと同じものにPopupControllerを使用できます PopupController

同じもののサンプルコードを次に示します。

popup = PopupController
        .create(self.navigationController!)
        .customize(
            [
                .layout(.center),
                .animation(.fadeIn),
                .backgroundStyle(.blackFilter(alpha: 0.8)),
                .dismissWhenTaps(true),
                .scrollable(true)
            ]
        )
        .didShowHandler { popup in
        }
        .didCloseHandler { popup in
    }
    let container = MTMPlayerAndCardSelectionVC.instance()
    container.closeHandler = {() in
        self.popup.dismiss()
    }

    popup.show(container)
0
Anjali jariwala

そのフレームに合うように境界プロパティを設定する必要があります。スーパービュープロパティをフレーム化し、ビュー自体の座標系でフレームを制限します。

0
bolek