190

背景を透明にして、View Controllerをモーダルに表示しようとしています。私の目標は、表示中と表示中の両方のView Controllerのビューを同時に表示できるようにすることです。問題は、プレゼンテーションのアニメーションが終了すると、プレゼンテーションのビュー コントローラーのビューが消えることです。

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}

ビューをサブビューとして追加できることはわかっていますが、何らかの理由でこの解決策を避けたいと思います。どうすれば修正できますか?

4

24 に答える 24

110

iOS 8.0 以降では、プロパティmodalPresentationStyleUIModalPresentationOverCurrentContextに設定することで実行できます。

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:presentedController animated:YES completion:nil];

添付画像参照

于 2015-01-12T19:40:30.193 に答える
106

この次のコードはiPadでのみ機能します。

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

サブビューを追加します。

これは非常に良い議論です。特にコメントを見てください。答えだけではありません。

モーダルビュー

もし私があなただったら、私はそれをしません。サブビューを追加して実行します。それは私に物事のより良いコントロールを与えるようです。

編集:

Paul Linsayが述べたように、iOS 8以降、必要なのはUIModalPresentationOverFullScreen、表示されるViewControllerのmodalPresentationStyleだけです。これは、navigationBarボタンとtabBarボタンについても説明します。

于 2012-10-05T07:12:35.377 に答える
44

このコードは、iOS6 および iOS7 の iPhone で正常に動作します。

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

この場合、スライドオン アニメーションが見逃されます。アニメーションを保持するには、次の「エレガントではない」拡張機能を引き続き使用できます。

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

presentingV が UINavigationController または UITabbarController 内にある場合は、そのコントローラーを presentingVC として操作する必要があります。

さらに、iOS7 では、UIViewControllerTransitioningDelegateプロトコルを適用するカスタム遷移アニメーションを実装できます。もちろん、この場合は透明な背景を得ることができます

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

まず、プレゼンテーションの前に設定する必要がありますmodalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

次に、2 つのプロトコル メソッドを実装する必要があります。

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}

CustomAnimatedTransitioning最後に、クラスでカスタム遷移を定義します

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    return 0.25;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}
于 2013-09-22T23:16:55.950 に答える
21

@VenuGopalTewari が提案したように、XCode 7 の Interface Builder でプレゼンテーション スタイルを設定するのに少し苦労しました。このバージョンでは、セグエのプレゼンテーション モードはないようOver Current Contextです。Over Full Screenしたがって、それを機能させるために、モードをDefault次のように設定しました。

ここに画像の説明を入力ここに画像の説明を入力

さらに、モーダルに表示されるビュー コントローラーの表示モードを次のように設定しますOver Full Screen

ここに画像の説明を入力

于 2015-10-14T10:26:24.297 に答える
19

モーダルに表示するセグエを作成し、そのセグエのプレゼンテーション プロパティを現在のコンテキストに設定すると、100% 動作します

ここに画像の説明を入力

于 2015-01-21T18:38:32.170 に答える
16

swift を使用したこの回答の解決策は次のとおりです。

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)
于 2017-07-06T16:21:39.820 に答える
14

背景が透明な PresentViewController - iOS 8 および iOS 9

MYViewController *myVC = [self.storyboard   instantiateViewControllerWithIdentifier:@"MYViewController"];
    myVC.providesPresentationContextTransitionStyle = YES;
    myVC.definesPresentationContext = YES;
    [myVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    [self.navigationController presentViewController:myVC animated:YES completion:nil];

そしてMYViewControllerで背景色を黒に設定し、不透明度を下げます

于 2016-06-23T08:06:01.107 に答える
12

It's a bit of hacky way, but for me this code works (iOS 6):

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

[self presentViewController:self.signInViewController animated:YES completion:^{
    [self.signInViewController dismissViewControllerAnimated:NO completion:^{
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
        [self presentViewController:self.signInViewController animated:NO completion:nil];
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    }];
}];

This code works also on iPhone

于 2013-09-24T11:29:40.873 に答える
11

このカテゴリは私にとってはうまくいきました(ios 7、8、および9)

Hファイル

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end

Mファイル

@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];

    }else{
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
         [self presentViewController:viewControllerToPresent animated:YES completion:completion];
    }
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
    UIViewController *presentingVC = self;
    UIViewController *root = self;
    while (root.parentViewController) {
        root = root.parentViewController;
    }
    UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
    root.modalPresentationStyle = UIModalPresentationCurrentContext;
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
        root.modalPresentationStyle = orginalStyle;
    }];
}
@end
于 2015-09-08T16:11:02.827 に答える
10

ストーリーボードを使用している場合は、次の手順に従います。

  1. ビュー コントローラー (V2) を追加し、必要に応じて UI をセットアップします
  • UIView を追加します - 背景を黒に、不透明度を 0.5 に設定します
  • 別の UIView(2) を追加します - ポップアップとして機能します (UIView と UIView(2) には同じレベル/階層が必要であることに注意してください。imageview をビューの子にしないでください。それ以外の場合、uiview の不透明度はUIView(2) に影響を与える)
  1. V2 をモーダルに表示

  2. セグエをクリックします。属性インスペクターで、プレゼンテーションを全画面表示に設定します。必要に応じてアニメーションを削除します

絵コンテ

  1. V2 を選択します。属性インスペクターで、プレゼンテーションを全画面表示に設定します。チェックはコンテキストを定義し、コンテキストを提供します

絵コンテ

  1. V2 の MainView を選択します (イメージを確認してください)。backgroundColor をClear Colorに設定する

絵コンテ

于 2017-09-20T03:24:06.237 に答える
7

提示されたView Controllerのinitメソッドにこれらの3行を追加しましたが、魅力的に機能します。

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];

編集(iOS 9.3で動作):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

ドキュメントに従って:

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

iOS 8.0 以降で利用できます。

于 2016-03-31T08:52:38.137 に答える
4

別の方法は、「コンテナ ビュー」を使用することです。alpha を 1 未満にして、seque で埋め込むだけです。XCode 5、ターゲット iOS7。iPhoneでテスト済み。

ここに画像の説明を入力

コンテナー ビューは iOS6 から使用できます。 それに関するブログ投稿へのリンク。

于 2013-08-14T09:46:56.117 に答える
3

これを行う非常に簡単な方法 (Storyboardsたとえば、 を使用) は次のとおりです。

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SomeStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SomeStoryboardViewController"];
// the key for what you're looking to do:
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.view.alpha = 0.50f;

[self presentViewController:vc animated:YES completion:^{
    // great success
}];

これはモーダルで表示UIViewControllerされStoryboardますが、背景は半透明になります。

于 2016-01-14T16:19:38.453 に答える
3

iOS 7-10 での作業

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}
于 2017-03-15T12:42:40.277 に答える
2

ここですべての良い回答とコメントを要約し、新しいものに移動している間もアニメーションを維持するために、ViewControllerこれが私がしたことです: (iOS 6 以降をサポート)

UINavigationController\を使用している場合UITabBarControllerは、次のようにします。

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

modalTransitionStyleそれを行うと、アニメーションが失われます。SomeViewControllerそれを解決するために、これをクラスに簡単に追加できます:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}
于 2014-07-09T14:10:48.840 に答える
1

iOS 7 および iOS 8 でテストされた完全な方法。

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end
于 2015-03-10T06:26:50.740 に答える
0

ナビゲーションmodalPresentationStyleをに設定UIModalPresentationCustom

提示されたView Controllerの背景色をクリアカラーとして設定します。

于 2017-07-05T08:28:31.570 に答える
0

appdelegate で:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[_window rootViewController]setModalPresentationStyle:UIModalPresentationCurrentContext];
    return YES;
}

最初のView Controllerで、次のビューをロードする必要がある場所から:

  NextViewController *customvc = [[NextViewController alloc]init];
    [self presentViewController:customvc animated:YES completion:^{

    }];

透明に追加される nextViewController で:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view insertSubview:backView atIndex:0];
}
于 2014-04-03T06:02:00.347 に答える