Как использовать presentModalViewController для создания прозрачного представления - PullRequest
79 голосов
/ 25 февраля 2009

Я отображаю модальное представление с

[self presentModalViewController:controller animated:YES];

Когда представление перемещается вверх по экрану, оно становится прозрачным в соответствии с настройкой в ​​xib-файле, из которого он создан, но после заполнения экрана оно становится непрозрачным.

Есть ли способ сохранить прозрачность вида?

Я подозреваю, что вид, над которым он находится, не отображается, а модальный вид становится непрозрачным.

Ответы [ 21 ]

4 голосов
/ 26 октября 2012

Я записал свои выводы по этому вопросу в другом вопросе , но суть в том, что вам нужно позвонить modalPresentationStyle = UIModalPresentationCurrentContext на все, кому в данный момент принадлежит полный экран. В большинстве случаев это что-то вроде rootViewController [UIApplication sharedApplication] .delegate.window. Это также может быть новый UIViewController, который был представлен с modalPresentationStyle = UIModalPresentationFullScreen.

Пожалуйста, прочитайте мой другой более подробный пост, если вам интересно, как я конкретно решил эту проблему. Удачи!

3 голосов
/ 10 августа 2013

Я создал открытую библиотеку soruce MZFormSheetController , чтобы представить лист модальной формы в дополнительном окне UIWindow. Вы можете использовать его, чтобы представить прозрачный модальный контроллер вида, даже настроить размер представленного контроллера представления.

3 голосов
/ 15 июля 2011

В моем состоянии у меня есть вид на тот же 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];

И это показывает, чего я хочу. надеюсь, это поможет кому-нибудь.

2 голосов
/ 17 января 2012

Вот категория, которую я создал, которая решит проблему.

    //
    //  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
1 голос
/ 23 сентября 2013

Этот код отлично работает на iPhone под iOS6 и iOS7:

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

Но при этом вы теряете анимацию «скольжения снизу».

1 голос
/ 17 июня 2016

После долгих исследований похоже, что это решит нашу проблему и послужит нашей цели.

создать переход из исходного VC в целевой VC с идентификатором.

например "goToDestinationViewController" давайте сделаем жизнь проще, давайте рассмотрим текущий контроллер представления, т.е. тот, который вам нужен за прозрачным представлением, в качестве источника и назначения в качестве пункта назначения

Теперь в исходном VC в viewDidLoad: или view

performSegueWithIdentifier("goToDestinationViewController", sender: nil)

хорошо, что мы на полпути. Теперь перейдите к вашей раскадровке. Нажмите на переход. который должен выглядеть так: 1011 * Segue *

изменить параметры на показанные.

Теперь приходит настоящее решение.

в viewDidLoad контроллера вида назначения добавьте этот код.

self.modalPresentationStyle = .Custom

............................................... ..........................ЭТО ПРОСТО...................... ............................................

1 голос
/ 09 июня 2016

Я нашел это элегантное и простое решение для 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();
        };

Наслаждайся этим! и, пожалуйста, оставьте несколько отзывов.

1 голос
/ 14 августа 2013

Альтернативный способ - использовать «вид контейнера». Просто сделайте альфу ниже 1 и вставьте с помощью seque. XCode 5, цель iOS7.

не могу показать изображение, недостаточно репутации)))

Контейнерное представление доступно с iOS6.

0 голосов
/ 01 августа 2014

Лучшее решение, с которым я столкнулся, - это использование метода addChildViewController. Вот отличный пример: Добавление представления дочернего контроллера представления к подпредставлению родительского контроллера представления

0 голосов
/ 02 сентября 2018

Я пытаюсь использовать несколько методов для решения, но все равно не получилось, наконец-то реализован следующий код.

Разрешение по 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...