iOS: модальный ViewController с прозрачным фоном

Я пытаюсь представить контроллер представления модально с прозрачным фоном. Моя цель - позволить одновременно отображать и представление, и представление контроллеров представлений. Проблема в том, что, когда анимация представления заканчивается, представление контроллера представления представления исчезает.

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

Я знаю, что могу просто добавить представление как подпредставление, но по какой-то причине я бы хотел избежать этого решения. Как я мог это исправить?


person Michael    schedule 05.10.2012    source источник
comment
@TheKing Похоже, Майкл, как и я, хочет, чтобы модальный вид был полупрозрачным, чтобы он выглядел как парящий слой геля над основным (представляющим) видом. Создает ощущение, что пользователь остается в текущем контексте при быстрой настройке, в отличие от перехода к некоторым другим основным функциям (в отдельном представлении).   -  person Basil Bourque    schedule 26.09.2013
comment
Это stackoverflow.com/q/27598846/1603234 заставляет меня улыбнуться, теперь ваша очередь :)   -  person Hemang    schedule 22.12.2014
comment
См. Мой ответ здесь stackoverflow.com/a/29794201/1606125 для iOS 8   -  person Pankaj Wadhwa    schedule 22.04.2015
comment
быстрая версия здесь stackoverflow.com/a/34578402/3380878   -  person Mojtabye    schedule 03.01.2016
comment
Для iOS 10 работает UIModalPresentationOverFullScreen как inigo333, упомянутый ниже.   -  person Josef Rysanek    schedule 31.12.2016
comment
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;   -  person Mitul Marsoniya    schedule 06.04.2017


Ответы (24)


Следующий код работает только на iPad.

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

Я бы пошел с добавлением дополнительного представления.

Вот очень хорошее обсуждение. Смотрите конкретно на комментарии. Не только ответ.

Модальный вид

На вашем месте я бы этого не сделал. Я бы добавил подвид и сделал это. Кажется, это дает мне лучший контроль над вещами.

РЕДАКТИРОВАТЬ:

Как упоминал Пол Линсей, начиная с iOS 8 все, что нужно, - это _2 _ для modalPresentationStyle представляемого ViewController. Это также будет охватывать кнопки navigationBar и tabBar.

person S.P.    schedule 05.10.2012
comment
Он действительно работает на iOS 7, а также на iPhone, дело в том, что вы должны указать modalPresentationStyle = UIModalPresentationCurrentContext в контроллере представления presenter, а не в представленном < / i> один. - person redent84; 04.06.2014
comment
Да, это работает, но ТОЛЬКО если вы установите его на более высоком ViewController иерархии представления. (например, NavigationController или экземпляр контроллера представления слайд-меню, например). - person iGranDav; 04.06.2014
comment
Как ни странно, в моем случае он работал только после установки модального стиля на UIModalPresentationCustom, и только если он был установлен прямо перед presentViewController, а не в viewDidLoad. - person mojuba; 03.05.2016
comment
Начиная с iOS 8, все, что нужно, - это UIModalPresentationOverFullScreen для модального стиля представления представленного ViewController. - person Paul Linsay; 24.05.2016
comment
Примерно после 1000 попыток я понял, что вам нужно установить modalPresentationStyle перед viewDidLoad. Я сделал это в конструкторе, и это сработало. - person bendytree; 21.05.2019

Для тех, кто пытается заставить это работать в iOS 8, "одобренный Apple" способ отображения прозрачного контроллера модального представления - это установить modalPresentationStyle на текущем контроллере ed на UIModalPresentationOverCurrentContext.

Это можно сделать в коде или установив свойства перехода в раскадровке.

Из документации UIViewController:

UIModalPresentationOverCurrentContext

Стиль представления, при котором содержимое отображается поверх содержимого только родительского контроллера представления. Представления под представленным контентом не удаляются из иерархии представлений после завершения презентации. Таким образом, если представленный контроллер представления не заполняет экран непрозрачным содержимым, основное содержимое просматривается.

При представлении контроллера представления во всплывающем окне этот стиль представления поддерживается только в том случае, если стиль перехода - UIModalTransitionStyleCoverVertical. Попытка использовать другой стиль перехода вызывает исключение. Однако вы можете использовать другие стили перехода (кроме частичного перехода curl), если родительский контроллер представления не находится в всплывающем окне.

Доступно в iOS 8.0 и новее.

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

В видеоролике «Просмотр улучшений контроллера в iOS 8» с WWDC 2014 это подробно рассматривается.

Примечание:

  • Обязательно дайте вашему представленному контроллеру представления четкий фоновый цвет, чтобы он на самом деле не был прозрачным!
  • Вы должны установить это перед представлением, т.е. установка этого параметра в viewDidLoad представленного ViewController не повлияет на
person Jeff C.    schedule 23.09.2014
comment
Примечание. Похоже, что цель, для которой необходимо установить modalPresentationStyle, изменилась. Например, в iOS 7, чтобы заставить это работать, мне нужно было установить modalPresentationStyle контроллера (ов) представления, который пытался открыть модальное окно для UIModalPresentationCurrentContext. Однако, чтобы заставить это работать в iOS8, мне нужно было установить modalPresentationStyle модального представления, которое будет отображаться в UIModalPresentationOverCurrentContext. - person u2Fan; 23.09.2014
comment
Если в раскадровках используются переходы, вам необходимо установить стиль представления там. По крайней мере, у меня это сработало. - person Julian B.; 17.04.2015
comment
Я добавил эти три строки в метод инициализации в представленном контроллере представления, и они работают как шарм: self.providesPresentationContextTransitionStyle = YES; self.definesPresentationContext = ДА; [самостоятельно setModalPresentationStyle: UIModalPresentationOverCurrentContext]; - person inigo333; 31.03.2016
comment
В iOS 8+ мне пришлось представить модальный объект из UINavigationController, поэтому представление от ребенка не дало мне того, что мне было нужно. Вместо этого sourceVC это self.navigationController. Кроме того, только после того, как я установил целевой стиль презентации как пользовательский, я смог увидеть его насквозь. [sourceVC setModalPresentationStyle:UIModalPresentationCurrentContext];, [targetVC setModalPresentationStyle:UIModalPresentationCustom]; Надеюсь, кому-то поможет. - person devdc; 17.05.2016
comment
Примечание. Позвоните presentedVC.modalPresentationStyle = UIModalPresentationOverCurrentContext в представляющую ВК. Не работает в представленном ВК. Поверьте, я пробовал. - person smileham; 09.06.2016
comment
Чтобы сделать представленный вид контроллера вызовом layoutSubviews (например, при изменении ориентации), используйте UIModalPresentationOverFullScreen вместо UIModalPresentationOverCurrentContext. - person SiavA; 18.08.2016
comment
Ответ @devdc помог, если ваш исходный VC является UINavigationController или UITabBarController. Отличный совет. - person antonio081014; 14.11.2018

В 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];

См. прикрепленное изображение

person sat20786    schedule 12.01.2015
comment
Это единственное решение, которое я мог заставить работать. Тоже очень просто. Просто добавьте это в свою презентационную VC перед модальным переходом. - person Siriss; 14.01.2015
comment
Xcoe 9.2 / iOS 11.2 swift .custom и .overFullScreen работают. - person William Hu; 31.03.2018
comment
И кажется, если вы установите .overFullScreen, текущий контроллер представления viewWillAppear не будет вызываться. - person William Hu; 31.03.2018
comment
Еще одна вещь: presentedController.view.backgroundColor = #color# следует записать в viewDidLoad presentedController, иначе жизнь presentedController прервется. - person DawnSong; 15.06.2018
comment
Переходя к этой теме в 2021 году с Xcode 12.2 и iOS 14.2, это единственное решение, которое сработало. - person Justin; 06.01.2021
comment
Большое спасибо! Это решение, которое я искал. - person Pedro Trujillo; 22.05.2021

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

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
    }
}
person malex    schedule 22.09.2013
comment
Подтверждено, что это работает. ПРИМЕЧАНИЕ: если ваш viewController находится внутри navigationController, убедитесь, что его modalPresentationStyle также установлен! - person mxcl; 13.12.2013
comment
Я думаю, что в наиболее распространенных случаях будет хорошей идеей рассматривать ваш контроллер навигации как представляющий VC. - person malex; 15.12.2013
comment
Да, с помощью этого modalPresentationStyle невозможно получить анимацию представления (( - person malex; 14.01.2014
comment
у меня только анимация опускания - person João Nunes; 14.01.2014
comment
Также запутано вращение. - person João Nunes; 14.01.2014
comment
Тем не менее работает :) Похоже, Apple на такой случай наплевать. - person malex; 14.01.2014
comment
Вы уверены, что правильно установили YOUR_COLOR? Например, представленныйVC.view.backgroundColor = [UIColor clearColor]; ? - person malex; 16.01.2014
comment
@alex да, это работает, извините: моя ошибка заключалась в том, чтобы установить для modalPresentationStyle значение UIModalPresentationCurrentContext для представленногоVC вместо prenstingVC. - person tiguero; 26.01.2014
comment
@mxcl И если ваш viewController navigationController сам находится внутри tabBarController, убедитесь, что его modalPresentationStyle также установлен;) - person Thomas C. G. de Vilhena; 19.05.2014
comment
@ user623396 напишите свою версию iOS. Он отлично работает, например, на iOS7. Убедитесь, что вы правильно используете PresentingVC и PresentingVC. - person malex; 24.06.2014
comment
Я добавил новый ответ с решением для быстрой анимации. - person Segev; 09.07.2014
comment
У меня это не сработало, потому что презентацияVC была в стеке навигации. Установка UIModalPresentationCurrentContext в navigationViewController помогла. - person user3099609; 13.08.2014
comment
@ user3099609, я забыл упомянуть тот факт, что во многих случаях представление VC на самом деле может быть контроллером навигации или контроллером панели вкладок. - person malex; 13.08.2014
comment
@tiguero У вас есть встроенный контроллер навигации? Вы должны изменить presentingVC на presentingVC.navigationViewController - person Mysteltainn; 16.09.2014
comment
@ ThomasC.G.deVilhena А как задать modelPresentationStyle tabBarController? Потому что вроде бы такого метода нет. - person Chanchal Raj; 08.04.2015
comment
@ChanchalRaj, modelPresentationStyle - это свойство UIViewController, который является суперклассом UITabBarController. - person malex; 08.04.2015
comment
Долго бился с анимацией. Ваше решение избавит меня от проблемы. Спасибо. - person Alex; 28.05.2015
comment
Ребята, я написал такой же код, и он у меня не работает. Я пытаюсь вот уже неделю, но безуспешно. Кто-нибудь может помочь? func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool { self.presentedViewController?.view.backgroundColor = UIColor.redColor() self.presentingViewController?.tabBarController?.modalPresentationStyle = UIModalPresentationStyle.CurrentContext return true; } - person Sategroup; 05.09.2015

Я немного боролся с Interface Builder XCode 7, чтобы установить стиль презентации, как предложил @VenuGopalTewari. В этой версии, похоже, нет режима представления Over Current Context или Over Full Screen для перехода. Таким образом, чтобы он заработал, я установил режим Default:

введите здесь описание изображения с помощью  введите описание изображения здесь

Кроме того, я установил режим представления модально представленного контроллера представления на Over Full Screen:

введите описание изображения здесь

person Bastian    schedule 14.10.2015
comment
Это сработало для меня, код не нужен. Я использую Xcode 7.2, swift, цель - iOS 8.0. - person LightMan; 15.02.2016
comment
У меня это тоже сработало. +1 за правильный ответ. Спасибо :) - person Augustine P A; 01.06.2016
comment
Лучший ответ здесь! - person shinyuX; 15.09.2016
comment
Нет кода = лучший ответ. Бастиан выигрывает эту игру. Плз всем +1 этот ответ. - person GeneCode; 12.01.2017
comment
Этот ответ сработал ... потратив на это больше часа - person user578386; 28.06.2019

Создайте переход для модального представления и установите для свойства Presentation этого перехода значение в текущем контексте, оно будет работать на 100%.

введите описание изображения здесь

person Venu Gopal Tewari    schedule 21.01.2015
comment
Восхищаюсь 100% уверенными, сработало! Ключ в том, чтобы нанести его на сегмент. Большое спасибо - person fullmoon; 26.02.2015
comment
Если ваш segue не подключен к кнопке, и вы вызываете его программно, обязательно установите идентификатор и вызовите performSegueWithIdentifier вместо presentViewController. - person user3344977; 26.08.2015
comment
Я попробовал все остальные ответы, но это единственный, который у меня сработал в iOS9. - person endavid; 20.03.2016

Решение этого ответа с использованием swift будет следующим.

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

PresentViewController с прозрачным фоном - в 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];

А в MYViewController установите черный цвет фона и уменьшите непрозрачность

person Ashwini Chougale    schedule 23.06.2016

Это немного хакерский способ, но для меня этот код работает (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

person Mak    schedule 24.09.2013
comment
Спасибо - это именно то, что мне было нужно - показывать начальный экран справки поверх основного главного экрана. Красивый! - person Matt H; 12.05.2014
comment
Сегодня я трачу почти 3 часа на просмотр и поиск решения, которое работает как для iOS7, так и для iOS8. Учитывая тот факт, что этому ответу 1,5 года, и я использую ECSlidingViewController, это единственное решение, которое сработало! Спасибо @Mak. - person Centurion; 21.04.2015
comment
Идеально. Кроме того, если вас не волнует анимация, 3 строки во внутреннем завершении работают отлично. Спасибо! - person RasTheDestroyer; 02.05.2015
comment
после 3 часов, проведенных без какого-либо успеха, нашел это, ура, жаль, что я не могу проголосовать больше: D - person alessioarsuffi; 30.10.2015

Эта категория работала у меня (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
person Ted    schedule 08.09.2015
comment
Я проверил все ответы .. но для меня ваш ответ отлично работает .. +1 за это. @Тед - person g212gs; 14.10.2015
comment
Я думал, что не могу найти решение. Большое спасибо! - person CopperCash; 25.05.2016

Если вы используете раскадровку, вы можете выполнить следующий шаг:

  1. Добавьте контроллер представления (V2), настройте пользовательский интерфейс так, как вы хотите
  • добавить UIView - установить черный фон и непрозрачность 0,5
  • добавьте еще один UIView (2), который будет служить вашим всплывающим окном (пожалуйста, обратите внимание, что UIView и UIView (2) должны иметь один и тот же уровень / иерархию. Не делайте imageview дочерним элементом представления, иначе непрозрачность uiview будет влияют на UIView (2))
  1. Представить V2 модально

  2. Щелкните переход. В инспекторе атрибутов установите для презентации значение Во весь экран. Удалите анимацию, если хотите

Раскадровка

  1. Выберите V2. В инспекторе атрибутов установите для презентации значение Во весь экран. Установите флажок Определяет контекст и предоставляет контекст.

Раскадровка

  1. Выберите MainView вашего V2 (пожалуйста, проверьте изображение). Установите для backgroundColor значение Очистить цвет.

Раскадровка

person dhin    schedule 20.09.2017

Я добавил эти три строки в метод инициализации в представленном контроллере представления и работает как шарм:

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

РЕДАКТИРОВАТЬ (работает на iOS 9.3):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

Согласно документации:

UIModalFullScreen Стиль представления представления, в котором представленное представление покрывает экран. Представления под представленным контентом не удаляются из иерархии представлений после завершения презентации. Таким образом, если представленный контроллер представления не заполняет экран непрозрачным содержимым, основное содержимое просматривается.

Доступно в iOS 8.0 и новее.

person inigo333    schedule 31.03.2016
comment
Работает на iOS 10.2. - person Josef Rysanek; 31.12.2016

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

введите описание изображения здесь

Представление контейнера доступно в iOS6. Ссылка на сообщение в блоге об этом.

person Mike Glukhov    schedule 14.08.2013

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

У него есть один простой метод, который делает это:

- (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];
}

Важно установить для свойства modalPresentationCapturesStatusBarAppearance значение YES и принудительно обновить внешний вид строки состояния, если представленный контроллер представления имеет другой 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+

person Pedro Mancheno    schedule 27.11.2014
comment
Спасибо за Ваш ответ. - person Salman Khakwani; 28.03.2016

Очень простой способ сделать это (например, используя 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 модально, но с полупрозрачным фоном.

person JaredH    schedule 14.01.2016

Работает на 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)
    }
}
person iluvatar_GR    schedule 15.03.2017

Чтобы подвести итоги всех хороших ответов и комментариев здесь и сохранить анимацию при переходе на новый 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;
}
person Segev    schedule 09.07.2014

Конечно, вы должны установить UIModalPresentationCurrentContext, но место для установки clearColor также очень важно! Вы не можете установить фон в функции viewDidLoad, установить его до загрузки представления, как в корневом контроллере представления или в функции инициализации контроллера, который будет представлен!

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

or

- (instancetype)init {

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

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

    return self;
}
person Santiago    schedule 06.12.2018
comment
Этот намек помог мне среди всех остальных. Спасибо за вашу помощь. - person Tomasz Nazarenko; 14.01.2019

Если вы используете модальный переход, обязательно установите его как это изображение (вы можете отключить анимацию, если хотите) введите  описание изображения здесь

person Ahmed    schedule 17.12.2014

Полный метод протестирован на 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
person BB9z    schedule 10.03.2015

Swift 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)
person Aleksey Shevchenko    schedule 15.04.2019

в appdelegate:

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

в вашем первом контроллере просмотра, откуда вы должны загрузить следующее представление:

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

    }];

в вашем nextViewController, который должен быть добавлен прозрачным:

- (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];
}
person Zaraki    schedule 03.04.2014

Экран входа в систему является модальным, то есть он находится поверх предыдущего экрана. Пока что у нас есть размытый фон, но он ничего не размывает; это просто серый фон.

Нам нужно правильно настроить наш модальный.

целевое изображение ссылки

  • Во-первых, нам нужно изменить цвет фона View Controller на Clear color. Это просто означает, что он должен быть прозрачным. По умолчанию этот вид белый.

  • Во-вторых, нам нужно выбрать переход, который ведет к экрану входа в систему, и в инспекторе атрибутов установить для презентации значение «Текущий контекст». Этот параметр доступен только при включенных классах автоматического макета и размера.

целевое изображение ссылки

person tinkl    schedule 15.04.2015

Установите modalPresentationStyle навигации на UIModalPresentationCustom

и установите цвет фона представленного контроллера представления как чистый цвет.

person Community    schedule 05.07.2017