モーダルビューを表示しています
[self presentModalViewController:controller animated:YES];
ビューが画面を上に移動すると、ビューが作成されたxibファイルの設定に従って透明になりますが、画面がいっぱいになると不透明になります。
ビューを透明に保つ方法はありますか?
モーダルビューが不透明になっているのではなく、配置されているビューがレンダリングされていないのではないかと思います。
モーダルビューを表示しています
[self presentModalViewController:controller animated:YES];
ビューが画面を上に移動すると、ビューが作成されたxibファイルの設定に従って透明になりますが、画面がいっぱいになると不透明になります。
ビューを透明に保つ方法はありますか?
モーダルビューが不透明になっているのではなく、配置されているビューがレンダリングされていないのではないかと思います。
viewcontroller.modalPresentationStyle = .FormSheet
回答:
ビューは引き続き透過的ですが、モーダルコントローラーがスタックの最上位に配置されると、その背後のビューは非表示になります(最上位のビューコントローラーの場合と同様)。解決策は、ビューを自分で手動でアニメーション化することです。その場合、behind-viewControllerは非表示になりません(「左」になっていないため)。
iOS 3.2以降、「トリック」なしでこれを行う方法があります。modalPresentationStyleプロパティのドキュメントを参照してください。viewControllerを表示するrootViewControllerがあります。成功するためのコードは次のとおりです。
viewController.view.backgroundColor = [UIColor clearColor];
rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[rootViewController presentModalViewController:viewController animated:YES];
このメソッドを使用すると、viewControllerの背景が透明になり、基になるrootViewControllerが表示されます。これはiPadでのみ機能するようです。以下のコメントを参照してください。
Over Current Context
、プレゼンテーションスタイルとして使用する必要があります。
これを機能させるために必要なもの:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
modalPresentationStyle
(ウィンドウのではなく)表示しているViewControllerにを設定することもできますrootViewController
。
コードを見たい人のために、透明なビューのコントローラーに追加したものを次に示します。
// Add this view to superview, and slide it in from the bottom
- (void)presentWithSuperview:(UIView *)superview {
// Set initial location at bottom of superview
CGRect frame = self.view.frame;
frame.origin = CGPointMake(0.0, superview.bounds.size.height);
self.view.frame = frame;
[superview addSubview:self.view];
// Animate to new location
[UIView beginAnimations:@"presentWithSuperview" context:nil];
frame.origin = CGPointZero;
self.view.frame = frame;
[UIView commitAnimations];
}
// Method called when removeFromSuperviewWithAnimation's animation completes
- (void)animationDidStop:(NSString *)animationID
finished:(NSNumber *)finished
context:(void *)context {
if ([animationID isEqualToString:@"removeFromSuperviewWithAnimation"]) {
[self.view removeFromSuperview];
}
}
// Slide this view to bottom of superview, then remove from superview
- (void)removeFromSuperviewWithAnimation {
[UIView beginAnimations:@"removeFromSuperviewWithAnimation" context:nil];
// Set delegate and selector to remove from superview when animation completes
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
// Move this view to bottom of superview
CGRect frame = self.view.frame;
frame.origin = CGPointMake(0.0, self.view.superview.bounds.size.height);
self.view.frame = frame;
[UIView commitAnimations];
}
iOS 8でこれを行うためのApple承認の方法は、modalPresentationStyleを「UIModalPresentationOverCurrentContext」に設定することです。
UIViewControllerのドキュメントから:
UIModalPresentationOverCurrentContext
親ViewControllerのコンテンツのみにコンテンツが表示される表示スタイル。提示されたコンテンツの下のビューは、提示が終了してもビュー階層から削除されません。したがって、提示されたView Controllerが不透明なコンテンツで画面を埋めない場合、基になるコンテンツが透けて見えます。
ポップオーバーでViewControllerを表示する場合、この表示スタイルは、遷移スタイルがUIModalTransitionStyleCoverVerticalである場合にのみサポートされます。別の遷移スタイルを使用しようとすると、例外がトリガーされます。ただし、親ビューコントローラがポップオーバーにない場合は、他の遷移スタイル(部分的なカール遷移を除く)を使用できます。
iOS8.0以降で利用できます。
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
WWDC2014の「iOS8でのコントローラーの進歩の表示」ビデオでこれについて詳しく説明します。
提示されたビューコントローラに明確な背景色を与えるようにしてください(そうしないと、不透明に見えます)。
別のオプションがあります。モーダルコントローラーを表示する前に、ウィンドウ全体のスクリーンショットをキャプチャします。キャプチャした画像をUIImageViewに挿入し、表示しようとしているコントローラのビューに画像ビューを追加します。その後、送り返します。画像ビューの上に別のビューを挿入します(背景は黒、アルファ0.7)。モーダルコントローラーを表示すると、透明に見えます。iOS4.3.1を実行しているiPhone4で試してみました。魅力のように。
これはかなり古いですが、私は次のように同じ問題を解決しました:iPhoneでナビゲーションコントローラーを提示する必要があるため、サブビューを追加することは実行可能な解決策ではありませんでした。
だから私がしたこと:
1)View Controllerを表示する前に、現在の画面のスクリーンショットを撮ります。
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
2)表示するビューコントローラを作成し、背景をサブビューとして追加して、バックに送信します。
UIViewController * presentingVC = [UIViewController new];
UIImageView * backgroundImageOfPreviousScreen = [[UIImageView alloc] initWithImage:backgroundImage];
[presentingVC.view addSubview:backgroundImageOfPreviousScreen];
[presentingVC.view sendSubviewToBack:backgroundImageOfPreviousScreen];
3)View Controllerを提示しますが、その前に新しいView Controllerで、viewDidLoadに透過ビューを追加します(私はILTranslucentViewを使用しました)
-(void)viewDidLoad
{
[super viewDidLoad];
ILTranslucentView * translucentView = [[ILTranslucentView alloc] initWithFrame:self.view.frame];
[self.view addSubview:translucentView];
[self.view sendSubviewToBack:translucentView];
}
そしてそれがすべてです!
これについての私の発見を別の質問に書き留めましたが、その要点はmodalPresentationStyle = UIModalPresentationCurrentContext
、現時点で全画面を所有しているものは何でも呼び出す必要があるということです。ほとんどの場合、それは[UIApplication sharedApplication] .delegate.windowのrootViewControllerです。また、で提示された新しいUIViewControllerである可能性もありますmodalPresentationStyle = UIModalPresentationFullScreen
。
私がこの問題を具体的にどのように解決したのか疑問に思っている場合は、他のはるかに詳細な投稿を読んでください。幸運を!
これはiOS8-9で私に働きました:
1-ビューコントローラーの背景をアルファで設定します
2-このコードを追加します:
TranslucentViewController *tvc = [[TranslucentViewController alloc] init];
self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[tvc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[self.navigationController presentViewController:tvc animated:YES completion:nil];
追加のUIWindowにモーダルフォームシートを表示するために、オープンソースライブラリMZFormSheetControllerを作成しました。これを使用して、透明度モーダルビューコントローラーを表示したり、表示されたビューコントローラーのサイズを調整したりすることもできます。
私の状態では、同じviewControllerでビューを持っています。したがって、UIViewを保持するための新しいViewControllerを作成します。alphaプロパティを設定して、そのビューを透明にします。次に、ボタンをクリックして、このコードを作成しました。よさそうだ。
UIGraphicsBeginImageContext(objAppDelegate.window.frame.size);
[objAppDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIViewController *controllerForBlackTransparentView=[[[UIViewController alloc] init] autorelease];
[controllerForBlackTransparentView setView:viewForProfanity];
UIImageView *imageForBackgroundView=[[UIImageView alloc] initWithFrame:CGRectMake(0, -20, 320, 480)];
[imageForBackgroundView setImage:viewImage];
[viewForProfanity insertSubview:imageForBackgroundView atIndex:0];
[self.navigationController presentModalViewController:controllerForBlackTransparentView animated:YES];
そしてそれは私が欲しいものを示しています。それが誰かを助けることを願っています。
これが私が作成した問題を解決するカテゴリーです。
//
// UIViewController+Alerts.h
//
#import <UIKit/UIKit.h>
@interface UIViewController (Alerts)
- (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated;
- (void)dismissAlertViewControllerAnimated:(BOOL)animated;
@end
//
// UIViewController+Alerts.m
//
#import "UIViewController+Alerts.h"
@implementation UIViewController (Alerts)
- (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated
{
// Setup frame of alert view we're about to display to just off the bottom of the view
[alertViewController.view setFrame:CGRectMake(0, self.view.frame.size.height, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)];
// Tag this view so we can find it again later to dismiss
alertViewController.view.tag = 253;
// Add new view to our view stack
[self.view addSubview:alertViewController.view];
// animate into position
[UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{
[alertViewController.view setFrame:CGRectMake(0, (self.view.frame.size.height - alertViewController.view.frame.size.height) / 2, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)];
}];
}
- (void)dismissAlertViewControllerAnimated:(BOOL)animated
{
UIView *alertView = nil;
// find our tagged view
for (UIView *tempView in self.view.subviews)
{
if (tempView.tag == 253)
{
alertView = tempView;
break;
}
}
if (alertView)
{
// clear tag
alertView.tag = 0;
// animate out of position
[UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{
[alertView setFrame:CGRectMake(0, self.view.frame.size.height, alertView.frame.size.width, alertView.frame.size.height)];
}];
}
}
@end
多くの研究の後、これは私たちの問題を解決し、私たちの目的を果たすように見えます。
識別子を使用して、送信元VCから宛先VCへのセグエを作成します。
たとえば、「goToDestinationViewController」を使用すると、作業が簡単になります。現在のビューコントローラ、つまり、透明なビューの背後にあるソースをソース、宛先を宛先として考えてみましょう。
現在、viewDidLoadのソースVCにあります:またはview
performSegueWithIdentifier("goToDestinationViewController", sender: nil)
中途半端です。次に、ストーリーボードに移動します。セグエをクリックします。これは次のようになります: セグエ
オプションを表示されているものに変更します。
今、本当の解決策が来ます。
デスティネーションビューコントローラーのviewDidLoadにこのコードを追加します。
self.modalPresentationStyle = .Custom
.................................................。 .......................それは簡単です........................。 ........................................。
self.modalPresentationStyle = .custom
Swift 3、Xcode 8で、背景が透明な実際のビューコントローラーをモーダルに表示する場合、設定は機能します。唯一の問題は、表示するビューコントローラーがタブバーコントローラーに埋め込まれている場合、タブバーが透明な前に表示されることです。背景ビュー。
tabBarController.tabBar.isHidden
をに設定する必要がありtrue
ます。
このコードは、iOS6およびiOS7のiPhoneで正常に機能します。
presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];
しかし、この方法に沿って、「下からスライド」のアニメーションを失います。
iOS 7以降向けのこのエレガントでシンプルなソリューションを見つけました!
iOS 8の場合、AppleはUIModalPresentationOverCurrentContextを追加しましたが、iOS 7以前では機能しないため、私の場合は使用できませんでした。
カテゴリを作成して、次のコードを入力してください。
.hファイル
typedef void(^DismissBlock)(void);
@interface UIViewController (Ext)
- (DismissBlock)presentController:(UIViewController *)controller
withBackgroundColor:(UIColor *)color
andAlpha:(CGFloat)alpha
presentCompletion:(void(^)(void))presentCompletion;
@end
.mファイル
#import "UIViewController+Ext.h"
@implementation UIViewController (Ext)
- (DismissBlock)presentController:(UIViewController *)controller
withBackgroundColor:(UIColor *)color
andAlpha:(CGFloat)alpha
presentCompletion:(void(^)(void))presentCompletion
{
controller.modalPresentationStyle = UIModalPresentationCustom;
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
__block UIView *overlay = [[UIView alloc] initWithFrame:keyWindow.bounds];
if (color == nil) {
color = [UIColor blackColor];
}
overlay.backgroundColor = color;
overlay.alpha = alpha;
if (self.navigationController != nil) {
[self.navigationController.view addSubview:overlay];
}
else if (self.tabBarController != nil) {
[self.tabBarController.view addSubview:overlay];
}
else {
[self.view addSubview:overlay];
}
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:controller
animated:true
completion:presentCompletion];
DismissBlock dismissBlock = ^(void) {
[self dismissViewControllerAnimated:YES completion:nil];
[UIView animateWithDuration:0.25
animations:^{
overlay.alpha = 0;
} completion:^(BOOL finished) {
[overlay removeFromSuperview];
}];
};
return dismissBlock;
}
@end
注:navigationContoller、tabBarControllerでも機能します。
使用例:
// Please, insure that your controller has clear background
ViewController *controller = [ViewController instance];
__block DismissBlock dismissBlock = [self presentController:controller
withBackgroundColor:[UIColor blackColor]
andAlpha:0.5
presentCompletion:nil];
// Supposed to be your controller's closing callback
controller.dismissed = ^(void) {
dismissBlock();
};
楽しめ!そして、いくつかのフィードバックを残してください。
これは私がこれまでに見つけた最良で最もクリーンな方法です:
@protocol EditLoginDelegate <NSObject>
- (void)dissmissEditLogin;
@end
- (IBAction)showtTransparentView:(id)sender {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"foo bar"
delegate:self
cancelButtonTitle:@"cancel"
destructiveButtonTitle:@"destructive"
otherButtonTitles:@"ok", nil];
[actionSheet showInView:self.view];
}
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet{
UIStoryboard *loginStoryboard = [UIStoryboard storyboardWithName:@"Login" bundle:nil];
self.editLoginViewController = [loginStoryboard instantiateViewControllerWithIdentifier:@"EditLoginViewController"];
self.editLoginViewController.delegate = self;
[self.editLoginViewController viewWillAppear:NO];
[actionSheet addSubview:self.editLoginViewController.view];
[self.editLoginViewController viewDidAppear:NO];
}
私が遭遇した最善の解決策は、addChildViewControllerメソッドを使用することです。優れた例を次に示します。子ViewControllerのビューを親ViewControllerのサブビューに追加します。
複数の方法を使用して解決しようとしましたが、それでも失敗しました。次のコードが最終的に実装されました。
Swiftによる解決:
// A.swift init method
modalPresentationStyle = .currentContext // or overCurrentContent
modalTransitionStyle = .crossDissolve // dissolve means overlay
次にBビューコントローラで:
// B.swift
let a = A()
self.present(a, animated: true, completion: nil)