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

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

[self presentModalViewController:controller animated:YES];

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

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

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

Ответы [ 21 ]

85 голосов
/ 07 апреля 2011

После iOS 3.2 есть способ сделать это без каких-либо «хитростей» - см. Документацию для свойства modalPresentationStyle . У вас есть rootViewController, который представит viewController. Итак, вот код успеха:

viewController.view.backgroundColor = [UIColor clearColor];
rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[rootViewController presentModalViewController:viewController animated:YES];

При использовании этого метода фон viewController будет прозрачным, а нижележащий rootViewController будет видимым. Обратите внимание, что это работает только на iPad, см. Комментарии ниже.

62 голосов
/ 26 февраля 2009

Ваше представление все еще прозрачно, но как только ваш модальный контроллер находится на вершине стека, представление позади него скрыто (как в случае с любым самым верхним контроллером представления). Решение состоит в том, чтобы вручную анимировать вид; тогда сзади-viewController не будет скрыт (так как вы не оставите его).

48 голосов
/ 19 января 2013

Что мне нужно, чтобы заставить это работать:

self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
24 голосов
/ 30 августа 2009

Для тех, кто хочет увидеть некоторый код, вот что я добавил в контроллер моего прозрачного представления:

// 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];    
}
19 голосов
/ 23 сентября 2014

Одобренный Apple способ сделать это в iOS 8 - установить для modalPresentationStyle значение UIModalPresentationOverCurrentContext.

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

UIModalPresentationOverCurrentContext

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

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

Доступно в iOS 8.0 и более поздних версиях.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/

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

Убедитесь, что на представленном контроллере представления задан чистый цвет фона (в противном случае он все равно будет выглядеть непрозрачным).

16 голосов
/ 26 марта 2011

Есть еще один вариант: перед показом модального контроллера сделайте снимок экрана всего окна. Вставьте захваченное изображение в UIImageView и добавьте представление изображения в представление контроллера, которое вы собираетесь показать. Затем отправьте обратно. Вставьте другой вид над изображением (фон черный, альфа 0,7). Покажите свой модальный контроллер, и похоже, что он был прозрачным. Только что попробовал на iPhone 4 под управлением iOS 4.3.1. Как очарование.

10 голосов
/ 08 марта 2014

это довольно старый, но я решил ту же проблему следующим образом: Поскольку мне нужно представить контроллер навигации в 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];
}

И это все!

5 голосов
/ 15 сентября 2014

Это похоже на ошибку в IOS 8, я использую контроллер навигации, и отображаемый контекст является контекстом меню навигации, который в нашем случае является контроллером скользящего меню.

Мы используем модуль 'TWTSideMenuViewController', '0.3' еще не проверял, нет ли проблем с библиотекой или методом, описанным выше.

5 голосов
/ 24 октября 2015

Это сработало для меня в 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];
4 голосов
/ 06 мая 2016

Я знаю, что это довольно старый вопрос. Я застрял в этой проблеме, и я смог получить руководство от этой темы. Так что выкладывать сюда, как у меня получилось :). Я использую раскадровку, и у меня есть переход к ViewController, который должен быть представлен. Контроллер вида имеет прозрачный цвет фона. Теперь в инспекторе Атрибутов segue я установил презентацию «По текущему контексту». И это сработало для меня Я разрабатываю для iPhone.

Attributes Inspector of the segue

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...