9

次のコードを使用して、viewcontroller を表示します。私の問題は次のとおりです。アニメーションが完了すると、透明なメインの背景が不透明な黒になります。

これを修正して clearColor のままにするにはどうすればよいですか?

UIViewController *menuViewController=[[UIViewController alloc]init];
   menuViewController.view.backgroundColor=[UIColor clearColor];
   menuViewController.view.tintColor=[UIColor clearColor];
   menuViewController.view.opaque=NO;

UIView *menuView=[[UIView alloc]initWithFrame:CGRectMake(0,[UIScreen mainScreen].bounds.size.height-200,320,200)];
   menuView.backgroundColor=[UIColor redColor];

[menuViewController.view addSubview:menuView];

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

更新:「自己」(プレゼンターのビューコントローラーのビュー) の内容を見ようとしています。

4

6 に答える 6

26

iOS 15 のアップデート

Apple は新しい API であるUISheetPresentationControllerを導入しました.medium()。よりカスタムなものを求めている場合は、元の答えが必要です。

let vc = UIViewController()
if let sheet = vc.presentationController as? UISheetPresentationController {
    sheet.detents = [.medium()]
}
self.present(vc, animated: true, completion: nil)

元の回答

iOS 7 では、View Controller を提示し、元の View Controller をフォームのようにその下に表示することができます。これを行うには、次の 2 つのことを行う必要があります。

  1. モーダル プレゼンテーション スタイルをカスタムに設定します。

    viewControllerToPresent.modalPresentationStyle = UIModalPresentationCustom;
    
  2. 移行デリゲートを設定します。

    viewControllerToPresent.transitioningDelegate = self;
    

この場合、デリゲートを自分自身に設定しましたが、別のオブジェクトにすることもできます。デリゲートは、次のように、プロトコルの 2 つの必須メソッドを実装する必要があります。

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init];
    semiModalAnimatedTransition.presenting = YES;
    return semiModalAnimatedTransition;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init];
    return semiModalAnimatedTransition;
}

この時点で、そのSemiModalAnimatedTransitionクラスはどこから来たのか考えているかもしれません。まあ、これはteehan+laxのブログから採用されたカスタム実装です。

クラスのヘッダーは次のとおりです。

@interface SemiModalAnimatedTransition : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) BOOL presenting;
@end

そして実装:

#import "SemiModalAnimatedTransition.h"

@implementation SemiModalAnimatedTransition

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return self.presenting ? 0.6 : 0.3;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    CGRect endFrame = fromViewController.view.bounds;
    
    if (self.presenting) {
        fromViewController.view.userInteractionEnabled = NO;
        
        [transitionContext.containerView addSubview:fromViewController.view];
        [transitionContext.containerView addSubview:toViewController.view];
        
        CGRect startFrame = endFrame;
        startFrame.origin.y = endFrame.size.height;
        
        toViewController.view.frame = startFrame;
        
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
            toViewController.view.frame = endFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
    else {
        toViewController.view.userInteractionEnabled = YES;
        
        [transitionContext.containerView addSubview:toViewController.view];
        [transitionContext.containerView addSubview:fromViewController.view];
        
        endFrame.origin.y = endFrame.size.height;
        
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
            fromViewController.view.frame = endFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
}

@end

最も簡単な解決策ではありませんが、ハッキングを回避し、うまく機能します。デフォルトでは、iOS はトランジションの最後に最初のビュー コントローラを削除するため、カスタム トランジションが必要です。

iOS 8 のアップデート

iOS 8 では、再び風景が変わりました。必要なことは、新しいプレゼンテーション スタイルを使用することだけです.OverCurrentContext

viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
于 2014-05-13T06:23:05.317 に答える
8

アップデート

ほとんどの場合、以下の Ric's answerのガイドラインに従うことをお勧めします。彼が言及しているmenuViewController.modalPresentationStyle = .overCurrentContextように、表示中のビュー コントローラーを表示し続けるための最も簡単な最新の方法です。

OPの問題に対する最も直接的な解決策を提供し、現在のView Controllerによって管理されているビューをすでに持っていて、それを表示する方法を探していたため、この回答を保持しています問題。


コメントで述べたように、これは透過性の問題ではありません (それ以外の場合は、背景が白くなることが予想されます)。アニメーションが完了するpresentViewController:animated:completion:と、表示中のビュー コントローラーはビジュアル スタックから実際に削除されます。表示されている黒は、ウィンドウの背景色です。

アニメーションを単純化するmenuViewControllerために をホストとして使用しているように見えるので、 をスキップして、既存のビュー コントローラーのビュー階層に追加し、自分でアニメーション化することを検討できます。menuViewmenuViewControllermenuView

于 2013-10-01T22:36:36.313 に答える
4

これは、解決するのがかなり簡単な問題です。カスタム ビュー トランジションを作成するのではなく、表示されるビュー コントローラーの modalPresentationStyle を設定するだけです。また、表示されるビュー コントローラーの背景色 (およびアルファ値) をストーリーボードまたはコード経由で設定する必要があります。

CustomViewController: UIViewController {
    override func viewDidLoad() {
      super.viewDidLoad()
      view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6)
    }
}

View Controllerを提示するIBActionコンポーネントで-

let vc = storyboard?.instantiateViewControllerWithIdentifier("customViewController") as! CustomViewController
vc.modalPresentationStyle = UIModalPresentationStyle.Custom
presentViewController(vc, animated: true, completion: nil)
于 2015-05-20T18:43:24.397 に答える
0

トップビューを透明にして、目的のビューの下に別のビューを追加し、そのビューの背景色を黒にして、アルファ 0.5 または任意の不透明度を設定してみてください。

于 2013-10-01T20:56:37.583 に答える