web-dev-qa-db-ja.com

iOS-半透明のモーダルビューコントローラー

最初のビューがモーダルビューの下にわずかに表示されるように、現在のビューの上にモーダルで少し透明な背景を持つビューコントローラーを表示したいと思います。

別の投稿で提案されているように、モーダルビューコントローラーのアルファ値を設定し、modalPresentationStyleUIModalPresentationCurrentContextに設定します。

その結果、アニメーション化するとビューの背景が透明になりますが、ビューコントローラーが配置されると、不透明な黒に変わります。解雇をアニメートしながら、透明に戻ります。

アクティブなときに透明にするにはどうすればよいですか?

iOS 6 and 7でテストしました。私が使用しているコードは次のとおりです。

MyModalViewController *viewController = [[MyModalViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navController setNavigationBarHidden:YES];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:NULL];
24
Drew C

iOS 8では、この目的専用の新しいモーダルプレゼンテーションスタイルが追加されました。

presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen

spec から:

UIModalPresentationOverFullScreen

表示されるビューが画面を覆うビュー表示スタイル。プレゼンテーションが終了しても、提示されたコンテンツの下のビューはビュー階層から削除されません。そのため、提示されたView Controllerが不透明なコンテンツで画面を満たさない場合、基になるコンテンツが透けて見えます。

40
jburns20

IOS 8以上をターゲットにしている場合は、モーダルプレゼンテーションスタイルを「現在のコンテキストに」に設定すれば完了です。 iOS 7以前の場合、カスタムの移行スタイルを作成して、移行後にプレゼンテーション画面が空白にならないようにする必要があります。それはかなり複雑です。

私が提示するソリューションは、多くの柔軟性を提供します。モーダルダイアログを表示する前にスクリーンショットを作成し、それをアプリケーションウィンドウの背景画像として設定します。デフォルトでは、その背景は黒です(これは、バックビューコントローラーが消えたときに表示されるものです)。背景をアプリのスクリーンショットに変更します。透明なビューのviewWillAppearまたはviewDidLoadメソッドでスクリーンショットを作成します。これは、モーダルダイアログだけでなく、プッシュセグエでも機能しますが、アニメーションは避けてください。一般に、背景のビューの位置に影響を与えるアニメーションは避けてください。アニメーションが変化すると、トランジションの終了時に元の位置にスナップされるように見えます。不要な効果を避けるために、viewDidDissapearで背景を以前の黒い画像にリセットすることをお勧めします。

このような背景画像のスタックを維持でき、複数の「透過的な」プッシュシーケンスを実行できます。または、いくつかのメイン画面の上に表示される複雑なメニューやディープメニューがあります。これらの多くの理由から、私はこのソリューションが独自の移行コードをロールするよりも優れていると思います。柔軟性が高く、実装が簡単です。アニメーションを自分で処理する必要はありません。

3
Radu Simionescu

モーダルが表示された後にBGビューコントローラーが表示されなくなるのは、アニメーションが完了した後、iOS 7のデフォルトの遷移によってBGビューが削除されるためです。独自のトランジションを定義し、BGビューを削除しないように設定した場合(アルファを変更するだけ)、透明なモーダルビューが表示されます。

2
Ali Ersöz

同じ問題が私にも起こりました。 カスタムアラートコントローラー に関する次のURLを見て解決しました。 UINavigationControllerを使用しても問題なく動作しました。

Swift

let viewController = UIViewController()
viewController.providesPresentationContextTransitionStyle = true
viewController.definesPresentationContext = true
viewController.modalPresentationStyle = .overCurrentContext
viewController.modalTransitionStyle = .crossDissolve
DispatchQueue.main.async {
    self.navigationController?.present(viewController, animated: true, completion: nil)
}

目的C

UIViewController *viewController = [UIViewController new];
viewController.providesPresentationContextTransitionStyle = true;
viewController.definesPresentationContext = true;
viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

dispatch_async(dispatch_get_main_queue(), ^{
    [self.navigationController presentViewController:viewController animated:true completion:nil];
});
2
Craz1k0ek

参考:構文は次のとおりです。

    childVC.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen
1
Eden

私の解決策はこれです:

任意のビュー、ナビゲーションバー、タブバーに表示されるカスタムの透明オーバーレイUIViewを作成します。

-ビューコントローラーが組み込まれているナビゲーションコントローラー(またはタブバーコントローラー)で、ナビゲーションコントローラーのビューのフレームと同じフレームのカスタムビューを作成します。

-次に、Origin.yをnavigationController.view.heightに設定して、画面外に設定します

-次に、2つの関数を作成します-(void)showOverlayと-(void)hideOverlayは、画面上と画面外のオーバーレイビューをアニメーション化します。

- (void)hideOverlay{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.3];

    CGRect frm = self.helpView.frame;//helpView is my overlay
    frm.Origin.y = self.offscreenOffset; //this is an Y offscreen usually self.view.height
    self.helpView.frame = frm;

    [UIView commitAnimations];
}

- (void)showOverlay{

    [self.view bringSubviewToFront:self.helpView];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.3];

    CGRect frm = self.helpView.frame;
    frm.Origin.y = self.onscreenOffset;
    self.helpView.frame = frm;

    [UIView commitAnimations];
}

-私のビューコントローラでは、呼び出すことができます

[(MyCustomNavCtrl *)self.navigationController showOverlay];
[(MyCustomNavCtrl *)self.navigationController hideOverlay];

そして、それはそれについてです。

1
user1670679

これが解決策です。

プレゼンテーションビューコントローラを作成します。このビューコントローラーのメインビューにbackViewを追加します。これにbackViewという名前を付けます。

SecondViewController.m

-(void)viewDidLoad
{
    // Make the main view's background clear, the second view's background transparent.
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view addSubview:backView];
}

これで、背景が半透明のView Controllerができました。 self.viewには何でも追加できます。残りは半透明になります。

その後、FirstViewController.m

self.modalPresentationStyle = UIModalPresentationCurrentContext;

[self presentViewController:secondViewController animated:YES completion:nil];
1
alper_k