programing

iOS: 배경이 투명한 모달 뷰 컨트롤러

muds 2023. 4. 26. 23:46
반응형

iOS: 배경이 투명한 모달 뷰 컨트롤러

저는 배경이 투명한 뷰 컨트롤러를 모델적으로 표시하려고 합니다.제 목표는 프레젠테이션 및 프레젠테이션 뷰 컨트롤러의 뷰를 동시에 표시하는 것입니다.문제는 프레젠테이션 애니메이션이 끝나면 프레젠테이션 뷰 컨트롤러의 뷰가 사라진다는 것입니다.

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}

보기를 하위 보기로 추가할 수도 있지만 어떤 이유에서인지 이 솔루션은 피하고 싶습니다.어떻게 고칠 수 있을까요?

8에서 "" 뷰를 표시하는 방법은 iOS 8을 설정하는 입니다.modalPresentationStyle 에 제시된 컨트롤러에서UIModalPresentationOverCurrentContext.

이 작업은 코드로 수행하거나 스토리보드에서 segue의 속성을 설정하여 수행할 수 있습니다.

UIView 컨트롤러 설명서에서 다음을 참조하십시오.

IMT2000 3GPP - UIModal 프레젠테이션 과전류 컨텍스트

내용이 상위 보기 컨트롤러의 내용 위에만 표시되는 프리젠테이션 스타일입니다.제시된 내용 아래의 보기는 프레젠테이션이 완료될 때 보기 계층에서 제거되지 않습니다.따라서 표시된 보기 컨트롤러가 화면을 불투명한 콘텐츠로 채우지 않으면 기본 콘텐츠가 표시됩니다.

뷰 컨트롤러를 팝업으로 표시할 때 이 표시 스타일은 전환 스타일이 UIModalTransitionStyleCoverVertical인 경우에만 지원됩니다.다른 전환 스타일을 사용하려고 하면 예외가 트리거됩니다.그러나 상위 뷰 컨트롤러가 팝업에 있지 않은 경우 다른 전환 스타일(부분 원곡선 전환 제외)을 사용할 수 있습니다.

iOS 8.0 이상에서 사용할 수 있습니다.

https://developer.apple.com/documentation/uikit/uiviewcontroller

WWDC 2014의 'View Controller Advances in iOS 8' 비디오는 이 부분에 대해 자세히 설명합니다.

참고:

  • 표시된 뷰 컨트롤러의 배경색을 선명하게 표시하여 실제로 비치지 않도록 하십시오.
  • 매개변수 설정을 표시하기 전에 이 매개변수를 설정해야 합니다.viewDidLoad의 영향을 ViewController의 경우에는 영향을 참조하십시오.

iOS 8.0 이상에서는 속성 modalpresentationStyle을 UIModalpresentationOverCurrentContext로 설정하여 수행할 수 있습니다.

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

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

첨부된 이미지 참조

다음 코드는 iPad에서만 작동합니다.

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

하위 뷰를 추가하는 것으로 하겠습니다.

여기 아주 좋은 토론이 있습니다.구체적으로 댓글을 보세요.정답뿐만 아니라.

모달 뷰

내가 당신이라면 그렇게 하지 않을 것입니다.하위 뷰를 추가하여 수행하겠습니다.그것은 제가 일을 더 잘 통제할 수 있게 해주는 것 같습니다.

편집:

Paul Linsay가 언급했듯이, iOS 8 이후에 필요한 것은 View 컨트롤러의 모달 프레젠테이션 스타일입니다.여기에는 탐색 모음 및 탭 모음 단추도 포함됩니다.

이 코드는 iOS6 및 iOS7의 iPhone에서 잘 작동합니다.

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

이 경우 슬라이드 온 애니메이션이 누락됩니다.애니메이션을 유지하려면 다음과 같은 "비우아한" 확장자를 사용할 수 있습니다.

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

PresentingV가 UINavigationController 또는 UITabbarController 내부에 있는 경우에는 해당 컨트롤러를 PresentingVC로 사용하여 작동해야 합니다.

또한 iOS7에서는 사용자 지정 전환 애니메이션을 구현할 수 있습니다.UIViewControllerTransitioningDelegate얻을, ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅠ

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

먼저, 발표하기 전에 설정해야 합니다.modalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

그런 다음 두 가지 프로토콜 방법을 구현해야 합니다.

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}

은 마막으사정전의정환의다니합을에서 사용자 입니다.CustomAnimatedTransitioning 시간

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    return 0.25;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}

@VenuGopalTewari가 제안한 대로 프레젠테이션 스타일을 설정하기 위해 XCode 7의 Interface Builder와 약간 애를 먹었습니다.버전에는 이버는없다가 것 .Over Current Context또는Over Full Screensegue에 대한 프레젠테이션 모드입니다.그래서 작동하기 위해 모드를 다음과 같이 설정했습니다.Default:

여기에 이미지 설명 입력 와 함께

를 추로모제뷰컨프트레모의러이다다드로 하였습니다.Over Full Screen:

여기에 이미지 설명 입력

모듈식으로 표시할 segue를 만들고 해당 segue의 Presentation 속성을 현재 컨텍스트에서 100% 작동하도록 설정합니다.

여기에 이미지 설명 입력

swift를 사용한 이 답변에 대한 해결책은 다음과 같습니다.

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)

투명 배경이 있는 PresentView 컨트롤러 - iOS 8 및 iOS 9

MYViewController *myVC = [self.storyboard   instantiateViewControllerWithIdentifier:@"MYViewController"];
    myVC.providesPresentationContextTransitionStyle = YES;
    myVC.definesPresentationContext = YES;
    [myVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    [self.navigationController presentViewController:myVC animated:YES completion:nil];

또한 MYView 컨트롤러에서 배경색을 검은색으로 설정하고 불투명도를 낮춥니다.

약간 진부한 방법이지만, 저에게 이 코드는 작동합니다(iOS 6).

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

[self presentViewController:self.signInViewController animated:YES completion:^{
    [self.signInViewController dismissViewControllerAnimated:NO completion:^{
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
        [self presentViewController:self.signInViewController animated:NO completion:nil];
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    }];
}];

이 코드는 iPhone에서도 작동합니다.

이 범주는 저에게 효과가 있었습니다(ios 7, 8, 9).

H파일

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end

M파일

@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];

    }else{
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
         [self presentViewController:viewControllerToPresent animated:YES completion:completion];
    }
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
    UIViewController *presentingVC = self;
    UIViewController *root = self;
    while (root.parentViewController) {
        root = root.parentViewController;
    }
    UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
    root.modalPresentationStyle = UIModalPresentationCurrentContext;
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
        root.modalPresentationStyle = orginalStyle;
    }];
}
@end

스토리보드를 사용하는 경우 다음 단계를 수행할 수 있습니다.

  1. 보기 컨트롤러(V2)를 추가하고 원하는 방식으로 UI를 설정합니다.
  • UIView 추가 - 배경을 검은색으로 설정하고 불투명도를 0.5로 설정
  • 팝업 역할을 할 다른 UIView(2)를 추가합니다(UIView와 UIView(2)의 수준/계층이 동일해야 함을 유의하십시오).이미지 보기를 보기의 자식으로 만들지 마십시오. 그렇지 않으면 UI 보기의 불투명도가 UI 보기에 영향을 미칩니다(2).
  1. V2 모듈식으로 표시

  2. segue를 클릭합니다.특성 검사기에서 프레젠테이션을 전체 화면으로 설정합니다.원하는 경우 애니메이션 제거

스토리보드

  1. V2를 선택합니다.특성 검사기에서 프레젠테이션을 전체 화면으로 설정합니다.컨텍스트 정의컨텍스트 제공 확인

스토리보드

  1. V2의 기본 보기(Pls)를 선택합니다.이미지 확인).배경색을 색상 지우기로 설정

스토리보드

제시된 뷰 컨트롤러의 init 메서드에 다음 세 개의 행을 추가했으며, 매력적으로 작동합니다.

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];

편집(iOS 9.3에서 작업):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

설명서에 따라:

UIModal PresentationOverFullScreen 표시된 보기가 화면을 덮는 보기 프레젠테이션 스타일입니다.제시된 내용 아래의 보기는 프레젠테이션이 완료될 때 보기 계층에서 제거되지 않습니다.따라서 표시된 보기 컨트롤러가 화면을 불투명한 콘텐츠로 채우지 않으면 기본 콘텐츠가 표시됩니다.

iOS 8.0 이상에서 사용할 수 있습니다.

다른 방법은 "컨테이너 보기"를 사용하는 것입니다.알파를 1 이하로 만들고 seque를 내장하면 됩니다.XCode 5, 목표 iOS7.iPhone에서 테스트했습니다.

여기에 이미지 설명 입력

iOS6에서 컨테이너 보기를 사용할 수 있습니다.그것에 대한 블로그 게시물 링크.

저는 제가 "중첩 모달"이라고 부르는 표현을 처리할 객체를 만들었습니다. 즉, 배경의 뷰를 유지하고 투명한 배경을 가진 모달을 사용할 수 있습니다.

단일의 간단한 방법으로 다음과 같은 작업을 수행할 수 있습니다.

- (void)presentViewController:(UIViewController *)presentedViewController
       fromViewController:(UIViewController *)presentingViewController
{
    presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
    presentedViewController.transitioningDelegate = self;
    presentedViewController.modalPresentationCapturesStatusBarAppearance = YES;

    [presentedViewController setNeedsStatusBarAppearanceUpdate];

    [presentingViewController presentViewController:presentedViewController
                                       animated:YES
                                     completion:nil];
}

설정하는 것이 중요합니다.modalPresentationCapturesStatusBarAppearanceYES된 뷰 경우 표시줄 합니다.preferredStatusBarStyle.

는 이개는다가합니다가 있어야 합니다.@property (assign, nonatommic) isPresenting

이 개체가 다음을 준수하도록 합니다.UIViewControllerAnimatedTransitioning그리고.UIViewControllerTransitioningDelegate프로토콜을 사용하고 다음 방법을 참조하십시오.

- (id)animationControllerForPresentedController:(UIViewController *)presented
                           presentingController:(UIViewController *)presenting
                               sourceController:(UIViewController *)source
{
    self.isPresenting = YES;

    return self;
}

- (id)animationControllerForDismissedController:(UIViewController *)dismissed
{
    self.isPresenting = NO;

    return self;
}

그리고:

- (NSTimeInterval)transitionDuration:(id)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id)transitionContext
{
    UIViewController* firstVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController* secondVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView* containerView = [transitionContext containerView];
    UIView* firstView = firstVC.view;
    UIView* secondView = secondVC.view;

    if (self.isPresenting) {
        [containerView addSubview:secondView];
        secondView.frame = (CGRect){
            containerView.frame.origin.x,
            containerView.frame.origin.y + containerView.frame.size.height,
            containerView.frame.size
        };

        firstView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        [UIView animateWithDuration:0.25 animations:^{
            secondView.frame = containerView.frame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
        } else {
        [UIView animateWithDuration:0.25 animations:^{
            firstView.frame = (CGRect){
                containerView.frame.origin.x,
                containerView.frame.origin.y + containerView.frame.size.height,
                containerView.frame.size
        };

        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
}

이것은 기본 모달 애니메이션을 모방한 슬라이드 인 더 바텀 애니메이션을 수행하지만 원하는 대로 만들 수 있습니다.

중요한 것은 프리젠테이션 뷰 컨트롤러의 뷰가 뒤쪽에 남아 투명한 효과를 만들 수 있다는 것입니다.

이 솔루션은 iOS 7+에서 작동합니다.

매우 간단한 방법(사용)Storyboards예)는 다음과 같습니다.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SomeStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SomeStoryboardViewController"];
// the key for what you're looking to do:
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.view.alpha = 0.50f;

[self presentViewController:vc animated:YES completion:^{
    // great success
}];

이는 다음과 같습니다.UIViewController순식간에Storyboard양식적으로, 그러나 반투명한 배경을 가지고 있습니다.

iOS 7-10을 위한 작업

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}

여기에 있는 모든 좋은 답변과 의견을 요약하고 새 것으로 이동하는 동안 애니메이션을 사용하는 것ViewController이렇게 했습니다. (iOS 6 이상 지원)

를 사용하는 경우UINavigationController\UITabBarController이것이 가야 할 길입니다.

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

당신이 그렇게 한다면 당신은 당신의 것을 잃게 될 것입니다.modalTransitionStyle애니매이션.이 문제를 해결하기 위해 쉽게 추가할 수 있습니다.SomeViewController등급:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}

물론 UIModal Presentation CurrentContext를 설정해야 하지만 clearColor를 설정하는 위치도 매우 중요합니다!viewDidLoad 함수에서 배경을 설정할 수 없습니다. 루트 뷰 컨트롤러나 표시할 컨트롤러의 init 함수처럼 뷰가 로드되기 전에 배경을 설정할 수 없습니다!

actionController.view.backgroundColor = [UIColor clearColor];
[self presentViewController:actionController animated:YES completion:nil];

또는

- (instancetype)init {

    self = [super initWithNibName:nil bundle:nil];

    if(self) {
        self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        [self.view setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}

스위프트 4.2

guard let someVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "someVC") as? someVC else {
    return
}
someVC.modalPresentationStyle = .overCurrentContext

present(someVC, animated: true, completion: nil)

모달세그를 사용하는 경우 반드시 이 이미지로 설정하십시오(원하는 경우 애니메이션을 끌 수 있습니다).여기에 이미지 설명 입력

iOS 7 및 iOS 8에서 테스트된 완전한 방법입니다.

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end

앱 대표자:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[_window rootViewController]setModalPresentationStyle:UIModalPresentationCurrentContext];
    return YES;
}

첫 번째 뷰에서 다음 뷰를 로드해야 하는 컨트롤러:

  NextViewController *customvc = [[NextViewController alloc]init];
    [self presentViewController:customvc animated:YES completion:^{

    }];

투명하게 추가할 다음 View 컨트롤러:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view insertSubview:backView atIndex:0];
}

로그인 화면은 모달로, 이전 화면의 맨 위에 위치합니다.지금까지 우리는 흐릿한 배경을 가지고 있지만, 그것은 아무것도 흐리지 않습니다. 단지 회색 배경일 뿐입니다.

모달을 제대로 설정해야 합니다.

이미지 링크 대상

  • 먼저 View 컨트롤러의 View 배경을 Clear color로 변경해야 합니다.그것은 단순히 투명해야 한다는 것을 의미합니다.기본적으로 보기는 흰색입니다.

  • 두 번째로 로그인 화면으로 이어지는 Segue를 선택하고 속성 관리자에서 프레젠테이션을 Over Current Context로 설정해야 합니다.이 옵션은 자동 레이아웃 및 크기 클래스가 활성화된 경우에만 사용할 수 있습니다.

이미지 링크 대상

탐색 설정modalPresentationStyle로.UIModalPresentationCustom

표시된 보기 컨트롤러의 배경색을 선명한 색으로 설정합니다.

언급URL : https://stackoverflow.com/questions/12741224/ios-modal-viewcontroller-with-transparent-background

반응형