web-dev-qa-db-ja.com

透過的なモーダルUIViewControllerを提示します

自分でカスタムalertView(iOS7 +用)を作成しようとしていますが、alertViewの表示に苦労しています。

背景が黒(アルファが0.25fに設定)のUIViewControllerと、サブビューとしてのalertViewがあります。

AlertViewを表示したい場合は、viewControllerをモーダルに表示します。

-(void) show 
{
    UIWindow* window = [[UIApplication sharedApplication] keyWindow];
    self.modalTransitionStyle = UIModalPresentationCustom;
    self.transitioningDelegate = self;
    [window.rootViewController presentViewController:self animated:YES completion:nil];
}

そして、これが私のアニメーターオブジェクトです:

-(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    NSLog(@"%s",__PRETTY_FUNCTION__);
    return 2;
}

-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    NSLog(@"%s",__PRETTY_FUNCTION__);

    UIView* toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    toView.alpha = 0;

    UIView* container = [transitionContext containerView];
    [container addSubview:toView];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        toView.alpha = 0.5;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

事は次のとおりです。モーダルVCは、本来のようにバックグラウンドでプレゼンテーションVCでフェードしますが、アニメーションが終了すると、プレゼンテーションVCはバックグラウンドから削除されます。

代わりに[transitionContext completeTransition:YES];を呼び出すと、提示するVCはバックグラウンドにありますが、モーダルVCはアニメーションの終了時に削除されるため、コンテキストがキャンセルされると思います'NO'を送信した場合のプレゼンテーション。

スナップショットを作成してモーダルVCのビューの背景として設定することなく、提示中のVCをバックグラウンドで維持する方法はありますか?

14
Imotep

参考までに、私はついにカスタムalertViewを「popUpパーツ」のUIViewのサブクラスにしました。それを表示するために、キーウィンドウのサブビューとしてalertViewを追加し、それを中央に配置する制約を付けて、その背後に透明な黒い背景ビューを配置します。

コントローラーではないので、自分でUIの回転を管理する必要があります(iOS 7の場合のみ、iOS 8のUIとうまく回転します)。

1
Imotep

私はこのソリューションを試しましたが、iOS7と8の両方で機能します。

if ([[UIDevice currentDevice].systemVersion integerValue] >= 8)
{
    //For iOS 8
    presentingViewController.providesPresentationContextTransitionStyle = YES;
    presentingViewController.definesPresentationContext = YES;
    presentedViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
}
else
{
    //For iOS 7
    presentingViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
}

注: 'presentingViewController'と 'の違いに注意してください)presentedViewController '。

38
Basem Saadawy

iOS8 +

IOS8 +の場合、以下のコードスニペットを使用できます

SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:secondViewController animated:YES completion:nil];    
5
arunjos007

私の場合はあなたの場合とは異なるかもしれませんが、その情報は会話に役立つかもしれません。

ストーリーボードで、セグエのプレゼンテーションを「フルスクリーン以上」と表示するように変更しました。

2
Carien van Zyl

ViewControllerは、提示またはプッシュするときに透過的であるとは想定されていません。サブビューとして追加してみてください。また、トランジションエフェクトの場合は、サブビューとして追加した直後にフレームを変更します。フレームを可視ビューの外側のどこかに作成し、アニメーション化してフレームを可視ビューに変更します。

お役に立てれば。

1
Nameet

あなたが見ているのはiOSのデフォルトの動作だと思います。

ビューコントローラは、モーダルビューコントローラとして提示された場合、不透明でないことは想定されていません。 iOSは、アニメーションが完了すると、下にあるView Controllerを削除して、提示されたViewControllerが画面全体を占めることになっているときに構成を高速化します。画面に表示されていない場合でも、ビューコントローラを描画する理由はありません(ビュー階層では複雑になる可能性があります)。

私はあなたの唯一の解決策はカスタムプレゼンテーションを行うことだと思います。

備考:私はこれをテストしませんでした。しかし、それはこのようになります。

/* Create a window to hold the view controller. */
UIWindow *presenterWindow = [[UIWindow alloc] init];

/* Make the window transparent. */
presenterWindow.backgroundColor = [UIColor clearColor];
presenterWindow.opaque = NO;

/* Set the window rootViewController to the view controller you
   want to display as a modal. */
presenterWindow.rootViewController = myModalViewController;

/* Setup animation */
CGRect windowEndFrame = [UIScreen mainScreen].bounds;
CGRect windowStartFrame = windowEndFrame;

/* Adjust the start frame to appear from the bottom of the screen. */
windowStartFrame.Origin.y = windowEndFrame.size.height;

/* Set the window start frame. */
presenterWindow.frame = windowStartFrame;

/* Put the window on screen. */
[presenterWindow makeKeyAndVisible];

/* Perform the animation. */
[UIView animateWithDuration:0.5
                      delay:.0
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     presenterWindow.frame = windowEndFrame;
                 }
                 completion:^(BOOL finished){
                     /* Your transition end code */
                 }];

ただし、これにより、UIViewControllerに組み込まれている現在のViewControllerロジックを使用するオプションがなくなります。提示されたViewControllerが完了したら、自分で理解する必要があります。次に、アニメーションを逆にして、画面からUIWindowを削除します。

1
Trenskow