2010-12-27 11 views

答えて

3

iOSでは、モーダルビューを表示する際に透過性はサポートされません。

+1

はい、私はそう思います。これまで、iOSはモーダルで透明性をサポートしていません。あなたの答えmachunterに感謝します。 :) – Rizki

+0

よく、助けにならないと知っていますが、 –

+0

これは間違っていますが、私はそれをtransperancyで行います。 – DeyaEldeen

0

おそらく、現在のビューにオーバーレイとしてUIViewを追加したいが、透明または半透明の背景でフルスクリーンにすることが望ましいでしょう。この質問への最初の答えを参照してください:

disable elements on UIView behind modal UIView

0

あなたはソートの、後方に作業する必要があります。 モーダルビューを読み込んで、その上にすべての要素を「手動で」Subviewとして追加します。この方法では隠れていません。 はい、それは多くのコーディングですが、行うことができます。 私はムービーを再生し、ムービープレーヤーのフレームサイズを小さくし、サブビューとしていくつかのボタンとテキストビューを投げて、余分な要素を画面に表示させました。 B

10

さて、presentModalViewControllerはこの動作を提供していませんが、それでも可能です。私は私のために働くカテゴリーを作りました(うまくいけばあなた)。追加ボーナスとして、同時にモーダルビューを解除して表示することに関連するクラッシュを防止します。

ヘッダファイル:

// 
// UIViewController+overView.h 
// Created by Kevin Lohman on 5/30/12. 
// 

#import <UIKit/UIKit.h> 

@interface UIViewController (OverView) 
- (void)presentOverViewController:(UIViewController *)modalViewController animated:(BOOL)animated; 
- (void)dismissOverViewControllerAnimated:(BOOL)animated; 
@end 

実装ファイル:

// 
// UIViewController+overView.m 
// Created by Kevin Lohman on 5/30/12. 
// 

#import "UIViewController+overView.h" 

@implementation UIViewController (OverView) 

#define kUIViewControllerOverViewDismissNotification @"OverViewDismissNotification" 

const float kUIViewControllerOverViewAnimationDuration = 0.75; 
const NSInteger kUIViewControllerOverViewTag = 8008135; // Arbitrary number, so as not to conflict 
- (void)overViewDismissed 
{ 
    [self autorelease]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kUIViewControllerOverViewDismissNotification object:self.view]; 
} 

- (void)presentOverViewController:(UIViewController *)modalViewController animated:(BOOL)animated 
{ 
    UIView *toView = self.view; 

    CGRect finalRect = CGRectIntersection([[UIScreen mainScreen] applicationFrame], self.view.frame); // Make sure it doesn't go under menu bar 
    modalViewController.view.frame = finalRect; 
    modalViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 
    modalViewController.view.tag = kUIViewControllerOverViewTag+modalViewController.modalTransitionStyle; // Hiding some info here :) 

    if(animated) 
    { 
     switch(modalViewController.modalTransitionStyle) 
     { 
      // Currently only cross dissolve and cover vertical supported... if you add support let me know. 
      case UIModalTransitionStyleCrossDissolve: 
      { 
       float beforeAlpha = modalViewController.view.alpha; 
       modalViewController.view.alpha = 0; 
       [toView addSubview:modalViewController.view]; 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        modalViewController.view.alpha = beforeAlpha; 
       }]; 
       break; 
      } 
      case UIModalTransitionStyleCoverVertical: 
      default: 
      { 
       modalViewController.view.frame = CGRectMake(modalViewController.view.frame.origin.x, modalViewController.view.frame.size.height, 
                  modalViewController.view.frame.size.width, modalViewController.view.frame.size.height); 
       [toView addSubview:modalViewController.view]; 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        modalViewController.view.frame = finalRect; 
       }]; 
       break; 
      } 
     } 
    } 
    else { 
     [toView addSubview:modalViewController.view]; 
    } 

    [modalViewController retain]; // Keep it around until we dismiss it. 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(overViewDismissed) name:kUIViewControllerOverViewDismissNotification object:modalViewController.view]; // Release will happen when this notification is posted 
} 

NSInteger transitionStyleForTag(tag) 
{ 
    if (tag >= kUIViewControllerOverViewTag && tag <= kUIViewControllerOverViewTag+UIModalTransitionStylePartialCurl) 
    { 
     return tag-kUIViewControllerOverViewTag; 
    } 
    else { 
     return -1; // Not a Over View 
    } 
} 

- (void)dismissOverViewControllerAnimated:(BOOL)animated 
{ 
    UIView *overView = transitionStyleForTag(self.view.tag) >= 0 ? self.view : nil; // Can dismiss ourselves 
    for(UIView *subview in self.view.subviews) 
    { 
     if(transitionStyleForTag(subview.tag) >= 0) 
      overView = subview; // Keep going, lets dismiss last presented first 
    } 
    if(!overView) return; // None to dismiss 

    if(animated) 
    { 
     switch(transitionStyleForTag(overView.tag)) 
     { 
      // Currently only cross dissolve and cover vertical supported... if you add support let me know. 
      case UIModalTransitionStyleCrossDissolve: 
      { 
       float beforeAlpha = overView.alpha; 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        overView.alpha = 0; 
       } completion:^(BOOL finished) { 
        [overView removeFromSuperview]; 
        overView.alpha = beforeAlpha; 
        [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView]; 
       }]; 
       break; 
      } 
      case UIModalTransitionStyleCoverVertical: 
      default: 
      { 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        overView.frame = CGRectMake(0, overView.frame.size.height, overView.frame.size.width, overView.frame.size.height); 
       } completion:^(BOOL finished) { 
        [overView removeFromSuperview]; 
        [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView]; 
       }]; 
       break; 
      } 
     } 
    } 
    else { 
     [overView removeFromSuperview]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView]; 
    } 
} 
@end 

その後は、単にpresentOverViewController代わりのpresentModalViewControllerとdismissOverViewControllerの代わりdissmissModalViewControllerを使用し、それを使用します。

制限のカップルがあります:

  1. あなたが画面全体をカバーするために をしたいとあなたは の内側にVCを持っているので、もしあなたが、ルート最もビューコントローラに提示しなければなりませんUINavigationController、それをナビゲーションコントローラに提示します。
  2. 古いiOSでローテーションに関する問題が発生することがありました。 ビルド(4.0またはそれ以上)
  3. 現在、クロスディゾルブおよびカバー垂直アニメーションのみを処理しています。
+0

すてきできちんとした解決策、ありがとう!しかし、2つの観察。 最初に、通知ハンドラの 'overViewDismissed'がモーダルビューコントローラではなく自己を解放し、クラッシュします。通知コードaddObserver/postNotificationを完全に削除し、現在の/解除メソッド外のモーダルビューコントローラのメモリを管理します。 第2に、[[[UIScreen mainScreen] applicationFrame] 'は必ずしも正しいフレームサイズを返しません。代わりに 'self.view.superview.frame'を使用します([この回答](http://stackoverflow.com/a/4052442/22764)を参照)。 –

+0

@VladimirGrigorovねえ、ありがとう、それはいくつかの悪いロジックがあるようです。私はこれを置くコードベースを覚えていませんが、私はそれをローカルに修正したと想像してください...あなたがまだどこかの固定バージョンをコンパイル/実行しているなら、あなたの発見に基づいて答えを編集できますか?私はそれを変更することができます(self.parentViewController autoreleaseに変更するだけですか?)ぼんやりと変更するために私に危険があります:) – BadPirate

+0

私は以前のコメントで述べたとおり通知コードを削除しました。テストに合格しました... –

9

私のための答えは、コードの1行だったが、モーダルビューコントローラを提示する前に、親ビューコントローラに追加:モーダルビューはいったん

self.modalPresentationStyle = UIModalPresentationCurrentContext; 

をこれが削除されてから親ビューを停止します追加されました。

+0

これは私にとってはうまくいかないようです。 –

+0

私を助けなかった。 – surfrider

+6

しかし、これは動作します。self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext; – surfrider

関連する問題