Прозрачный модальный вид на контроллере навигации - PullRequest
71 голосов
/ 11 мая 2009

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

Ответы [ 19 ]

109 голосов
/ 13 мая 2009

Модальный вид будет охватывать вид, над которым он помещен, а также панель навигации для вашего контроллера навигации. Однако, если вы используете -presentModalViewController: animated: подхода, то после завершения анимации только что покрытый вид фактически исчезнет, ​​что сделает любую прозрачность вашего модального представления бессмысленной. (Вы можете убедиться в этом, реализовав методы -viewWillDisappear: и -viewDidDisappear: в вашем корневом контроллере представления).

Вы можете добавить модальное представление непосредственно в иерархию представления следующим образом:

UIView *modalView =
    [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
modalView.opaque = NO;
modalView.backgroundColor =
    [[UIColor blackColor] colorWithAlphaComponent:0.5f];

UILabel *label = [[[UILabel alloc] init] autorelease];
label.text = @"Modal View";
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[label sizeToFit];
[label setCenter:CGPointMake(modalView.frame.size.width / 2,
                                modalView.frame.size.height / 2)];
[modalView addSubview:label];

[self.view addSubview:modalView];

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

TransparentModalViewAppDelegate *delegate = (TransparentModalViewAppDelegate *)[UIApplication sharedApplication].delegate;
[delegate.window addSubview:modalView];
18 голосов
/ 10 сентября 2012

Самый простой способ - использовать modalPresentationStyle свойство navigationController (но вам придется создавать анимацию самостоятельно):

self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalViewController animated:NO];
modalViewController.view.alpha = 0;
[UIView animateWithDuration:0.5 animations:^{
    modalViewController.view.alpha = 1;
}];
12 голосов
/ 11 мая 2009

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

Пример кода для контроллера корневого представления:

- (void)viewDidLoad {
  OverlayViewController *o = [OverlayViewController sharedOverlayViewController];
  [self.view addSubview:o.view];
}

Пример кода, который вы можете использовать для отображения модального вида:

[[OverlayViewController sharedOverlayViewController] presentModalViewController:myModalViewController animated:YES];

На самом деле я не использовал -presentModalViewController:animated: с моим OverlayViewController, но я ожидаю, что это будет прекрасно работать.

См. Также: Как выглядит ваш синглтон Objective C?

8 голосов
/ 20 октября 2011

У меня была такая же проблема, и для этого решение состоит в том, чтобы добавить модальное представление с помощью addSubview: и анимировать изменение в иерархии представления с помощью animateWithDuration UIView: задержка: параметры: анимация: завершение:

Я добавил свойство и 2 метода в подкласс UIViewController (FRRViewController), который включает другие функции. Я скоро опубликую весь материал на gitHub, но до тех пор вы можете увидеть соответствующий код ниже. Для получения дополнительной информации, вы можете проверить мой блог: Как отобразить прозрачный модальный контроллер вида .

#pragma mark - Transparent Modal View
-(void) presentTransparentModalViewController: (UIViewController *) aViewController 
                                     animated: (BOOL) isAnimated 
                                    withAlpha: (CGFloat) anAlpha{

    self.transparentModalViewController = aViewController;
    UIView *view = aViewController.view;

    view.opaque = NO;
    view.alpha = anAlpha;
    [view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UIView *each = obj;
        each.opaque = NO;
        each.alpha = anAlpha;
    }];

    if (isAnimated) {
        //Animated
        CGRect mainrect = [[UIScreen mainScreen] bounds];
        CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);


        [self.view addSubview:view];
        view.frame = newRect;

        [UIView animateWithDuration:0.8
                         animations:^{
                             view.frame = mainrect;
                         } completion:^(BOOL finished) {
                             //nop
                         }];

    }else{
        view.frame = [[UIScreen mainScreen] bounds];
        [self.view addSubview:view];
    }






}

-(void) dismissTransparentModalViewControllerAnimated:(BOOL) animated{

    if (animated) {
        CGRect mainrect = [[UIScreen mainScreen] bounds];
        CGRect newRect = CGRectMake(0, mainrect.size.height, mainrect.size.width, mainrect.size.height);
        [UIView animateWithDuration:0.8
                         animations:^{
                             self.transparentModalViewController.view.frame = newRect;
                         } completion:^(BOOL finished) {
                             [self.transparentModalViewController.view removeFromSuperview];
                             self.transparentModalViewController = nil;
                         }];
    }


}
7 голосов
/ 10 апреля 2012

Вот что я сделал, чтобы решить эту проблему - Google детали, но этот подход работал очень хорошо для меня:

  • Сделайте скриншот основного вида. https://devforums.apple.com/message/266836 - это приводит к готовому методу, который возвращает UIView для текущего экрана.
  • Передать скриншот модальному виду (я использовал свойство)
  • Представить модальный вид
  • В viewDidAppear контроллера модального вида установите изображение как UIImageView с индексом 0. Отрегулируйте вертикальное положение изображения по высоте строки состояния.
  • В представлении контроллера модального вида исчезнет, ​​снова удалите изображение

Эффект:

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

Я пытался анимировать в своем собственном режиме наложения, но он работал не очень хорошо. Я получил аварию без указания того, что разбилось. Вместо того, чтобы преследовать это, я сделал bg view & Works очень хорошо.

Код в модальном представлении - я думаю, вы можете выяснить остальное, а именно установить свойство modalView.bgImage ...

- (void)viewDidAppear:(BOOL)animated {
    // background
    // Get status bar frame dimensions
    CGRect statusBarRect = [[UIApplication sharedApplication] statusBarFrame];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:self.bgImage];
    imageView.tag = 5;
    imageView.center = CGPointMake(imageView.center.x, imageView.center.y - statusBarRect.size.height);
    [self.view insertSubview:imageView atIndex:0];
}

- (void)viewWillDisappear:(BOOL)animated {
    [[self.view viewWithTag:5] removeFromSuperview];
}
4 голосов
/ 02 июля 2012
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:newview animated:YES];

и убедитесь, что вы установили прозрачность фона модального вида,

self.view.background = .... альфа: 0.x;

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

, если вы установили modalPresentationStyle для контроллера модального представления в:

viewController.modalPresentationStyle = 17;

Вид на заднем плане не удаляется. (TWTweetComposeViewController использует его).

Я не пытался пройти проверку App Store с этим кодом, хотя

3 голосов
/ 19 октября 2010

Да, вам нужно добавить вид вручную, и если вы хотите скользить снизу или что-то еще, вы тоже должны сделать анимацию самостоятельно.

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

Вы можете найти документацию в этом блоге , код на github

3 голосов
/ 17 мая 2009

Этот пост о с полупрозрачным представлением «Загрузка ...» может дать несколько советов о том, как действовать.

2 голосов
/ 19 марта 2012

Я исследовал эту проблему на прошлой неделе. Я попробовал все различные ответы и примеры, найденные в Google и здесь, на StackOverflow. Никто из них не работал так хорошо.

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

Вот веб-страница, которая показывает пример того, как это сделать .

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