모달 뷰를 표시하고 있습니다.
[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
프레젠테이션보기 컨트롤러에서을 설정할 수도 있습니다 (창 대신 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
콘텐츠가 상위 뷰 컨트롤러의 콘텐츠 위에 만 표시되는 프레젠테이션 스타일입니다. 프레젠테이션이 완료 될 때 프레젠테이션 된 콘텐츠 아래의보기는보기 계층 구조에서 제거되지 않습니다. 따라서 제시된 뷰 컨트롤러가 불투명 한 콘텐츠로 화면을 채우지 않으면 기본 콘텐츠가 표시됩니다.
팝 오버에 뷰 컨트롤러를 표시 할 때이 프레젠테이션 스타일은 전환 스타일이 UIModalTransitionStyleCoverVertical 인 경우에만 지원됩니다. 다른 전환 스타일을 사용하려고하면 예외가 발생합니다. 그러나 상위 뷰 컨트롤러가 팝 오버에없는 경우 다른 전환 스타일 (부분 컬 전환 제외)을 사용할 수 있습니다.
iOS 8.0 이상에서 사용할 수 있습니다.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
WWDC 2014의 'View Controller Advancements in iOS 8'비디오에서 이에 대해 자세히 설명합니다.
제시된 뷰 컨트롤러에 명확한 배경색을 지정해야합니다 (그렇지 않으면 여전히 불투명하게 나타납니다).
또 다른 옵션이 있습니다. 모달 컨트롤러를 표시하기 전에 전체 창의 스크린 샷을 캡처합니다. 캡처 된 이미지를 UIImageView에 삽입하고 표시하려는 컨트롤러의보기에 이미지보기를 추가합니다. 그런 다음 다시 보내십시오. 이미지보기 위에 다른보기를 삽입합니다 (배경 검정색, 알파 0.7). 모달 컨트롤러를 보여 주면 투명 해 보입니다. iOS 4.3.1을 실행하는 iPhone 4에서 사용해 보았습니다. 매력처럼.
이것은 꽤 오래되었지만 다음과 같은 문제를 해결했습니다. iPhone에 탐색 컨트롤러를 표시해야하므로 하위보기를 추가하는 것은 실행 가능한 솔루션이 아닙니다.
그래서 내가 한 일 :
1) 뷰 컨트롤러를 표시하기 전에 현재 화면의 스크린 샷을 찍습니다.
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) 뷰 컨트롤러를 제시하되 그 전에 새 뷰 컨트롤러에서 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입니다. .NET Framework와 함께 제공된 새로운 UIViewController 일 수도 있습니다 modalPresentationStyle = UIModalPresentationFullScreen
.
이 문제를 어떻게 구체적으로 해결했는지 궁금하다면 다른 훨씬 더 자세한 게시물을 읽으십시오. 행운을 빕니다!
이것은 iOS 8-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에 모달 양식 시트를 표시하기 위해 오픈 soruce 라이브러리 MZFormSheetController 를 만들었습니다 . 투명도 모달 뷰 컨트롤러를 표시하는 데 사용할 수 있으며 제시된 뷰 컨트롤러의 크기를 조정할 수도 있습니다.
내 상태에서는 동일한 viewController에 대한보기가 있습니다. 따라서 UIView를 유지하기위한 새로운 뷰 컨트롤러를 만드십시오. 알파 속성을 설정하여 해당 뷰를 투명하게 만듭니다. 그런 다음 버튼을 클릭하여이 코드를 작성했습니다. 좋아 보인다.
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 로의 segue를 만듭니다.
예를 들어 "goToDestinationViewController"는 삶을 쉽게 만들어줍니다. 현재 뷰 컨트롤러를 고려해 봅시다. 즉, 투명 뷰 뒤에 원하는 컨트롤러를 소스로, 대상을 대상으로 간주합니다.
이제 viewDidLoad의 소스 VC에서 : 또는보기
performSegueWithIdentifier("goToDestinationViewController", sender: nil)
반쯤 끝났습니다. 이제 스토리 보드로 이동합니다. segue를 클릭하십시오. 다음과 같이 보일 것입니다 : segue
표시되는 옵션을 변경하십시오.
이제 진정한 해결책이 있습니다.
대상 뷰 컨트롤러의 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 메서드를 사용하는 것입니다. 다음은 훌륭한 예 입니다. 상위 뷰 컨트롤러의 하위 뷰에 하위 뷰 컨트롤러의 뷰를 추가합니다 .
해결하기 위해 여러 가지 방법을 사용하려고 시도했지만 여전히 실패했으며 다음 코드가 마침내 구현되었습니다.
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)