Прозрачный модальный вид на навигационном контроллере
Я пытаюсь создать прозрачный модальный вид поверх моего навигационного контроллера. Кто-нибудь знает, возможно ли это?
19 ответов:
модальный вид будет охватывать вид, который он нажимается сверху, а также панель навигации для вашего навигационного контроллера. Однако, если вы используете-presentModalViewController: animated: approach, то после завершения анимации только что покрытый вид фактически исчезнет, что делает любую прозрачность вашего модального вида бессмысленной. (Это можно проверить, реализовав методы-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];
самый простой способ-это использовать modalPresentationStyle собственность navigationController (но вам придется сделать анимацию самостоятельно):
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentModalViewController:modalViewController animated:NO]; modalViewController.view.alpha = 0; [UIView animateWithDuration:0.5 animations:^{ modalViewController.view.alpha = 1; }];
Я выполняю это наиболее легко, настроив "OverlayViewController", который находится выше всех других подвидов моего окна или корневого представления. Установите это в своем делегате приложения или корневом контроллере представления и сделайте OverlayViewController одноэлементным, чтобы к нему можно было получить доступ из любого места в иерархии кода или контроллера представления. Затем вы можете вызывать методы для отображения модальных представлений, отображения индикаторов активности и т. д., Когда вам нужно, и они могут потенциально охватывать любые панели вкладок или навигацию контроллеры.
пример кода для корневого контроллера вида:
- (void)viewDidLoad { OverlayViewController *o = [OverlayViewController sharedOverlayViewController]; [self.view addSubview:o.view]; }
пример кода, который можно использовать для отображения модального представления:
[[OverlayViewController sharedOverlayViewController] presentModalViewController:myModalViewController animated:YES];
Я на самом деле не используется
-presentModalViewController:animated:
С моим OverlayViewController, но я ожидаю, что это будет работать просто отлично.Читайте также: как выглядит ваша цель-c синглтон?
У меня была такая же проблема, и для решения этой проблемы нужно добавить модальное представление с addSubview: и анимировать изменение в иерархии представлений с помощью animateWithDuration:delay: options: animations:completion:
Я добавил свойство и 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; }]; } }
вот что я сделал, чтобы решить эту проблему-Google детали, но этот подход работал очень хорошо для меня:
- сделайте снимок экрана основного вида. https://devforums.apple.com/message/266836 - это приводит к готовому методу, который возвращает UIView для текущего экрана.
- передайте скриншот в модальное представление (я использовал свойство)
- представьте модальный вид
- в контроллере модального вида viewDidAppear, с помощью UIImageView с индексом 0. Отрегулируйте вертикальное положение изображения по высоте строки состояния.
- в viewWillDisappear модальное представление-контроллер, удалить изображение снова
эффект:
- вид анимируется, как и любой модальный вид - полупрозрачные части модального вида скользят по существующему виду
- как только анимация останавливается, фон устанавливается на скриншот - это делает его появляются, как будто старый вид все еще находится под ним, хотя это не так.
- как только начинается анимация исчезновения модального вида, изображение удаляется. ОС тем временем показывает старый вид навигации, поэтому модальный вид прозрачно скользит прочь и из поля зрения, как и следовало ожидать.
Я попытался анимировать в моем собственном представлении наложения, но это не очень хорошо работает. Я получил аварию без указания того, что разбилось. Вместо того, чтобы преследовать это, я сделал 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]; }
self.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentModalViewController:newview animated:YES];
и убедитесь, что вы настроили фон модального вида, чтобы быть прозрачным,
self.вид.фон. = ... Альфа:0.x;
Если вы установите modalPresentationStyle для контроллера модального вида:
viewController.modalPresentationStyle = 17;
посмотреть в фоновом режиме не удаляется. (TWTweetComposeViewController использовать его).
Я не пытался пройти обзор App Store с этим кодом, хотя
этот пост про отображение полупрозрачной " загрузки..."вид может дать несколько советов о том, как продолжить.
Я изучал этот же вопрос на прошлой неделе. Я попробовал все различные ответы и примеры, найденные в Google и здесь на StackOverflow. Никто из них не работал так хорошо.
будучи новичком в программировании iOS, я не знал о том, что называется
UIActionSheet
. Поэтому, если вы пытаетесь выполнить это, чтобы показать модальное наложение кнопок (например, модальный запрос кого-то, как они хотят поделиться чем-то), просто используйтеUIActionSheet
.здесь a веб-страница, которая показывает пример того, как это сделать.
Я получил эту идею от https://gist.github.com/1279713
Приготовление: В модальном представлении xib (или сцене с использованием раскадровки) я настраиваю полноэкранный фон UIImageView (зацепите его .H-файл и дать ему свойство "backgroundImageView") с 0.3 Альфа. И я установил вид (UIView) цвет фона как обычный черный.
идея: Затем в "viewDidLoad" контроллера модального вида я снимаю скриншот с экрана исходный статус и установить это изображение в фоновом режиме UIImageView. Установите начальную точку Y на -480 и позвольте ей скользить до точки Y 0, используя длительность 0,4 секунды с опцией анимации EaseInOut. Когда мы отклоняем контроллер вида,просто сделайте обратное.
код для класса контроллера модального вида
.H-файл:
@property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView; - (void) backgroundInitialize; - (void) backgroundAnimateIn; - (void) backgroundAnimateOut;
.файл м:
- (void) backgroundInitialize{ UIGraphicsBeginImageContextWithOptions(((UIViewController *)delegate).view.window.frame.size, YES, 0.0); [((UIViewController *)delegate).view.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); backgroundImageView.image=screenshot; } - (void) backgroundAnimateIn{ CGRect backgroundImageViewRect = backgroundImageView.frame; CGRect backgroundImageViewRectTemp = backgroundImageViewRect; backgroundImageViewRectTemp.origin.y=-480; backgroundImageView.frame=backgroundImageViewRectTemp; [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{ backgroundImageView.frame=backgroundImageViewRect; } completion:^(BOOL finished) { }]; } - (void) backgroundAnimateOut{ CGRect backgroundImageViewRect = backgroundImageView.frame; backgroundImageViewRect.origin.y-=480; [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationCurveEaseInOut animations:^{ backgroundImageView.frame=backgroundImageViewRect; } completion:^(BOOL finished) { }]; }
в viewDidLoad, просто звоните:
[self backgroundInitialize]; [self backgroundAnimateIn];
в любом месте мы отклоняем контроллер модального вида, мы называем:
[self backgroundAnimateOut];
обратите внимание, что это всегда будет анимировать фоновое изображение. Поэтому, если этот стиль перехода контроллера модального вида (или стиль перехода segue) не установлен в "вертикальное покрытие", вам может не потребоваться вызывать методы анимации.
Я, наконец, выполнил это для интерфейса навигации или панели вкладок, объединив контроллер вида наложения (см.: ответ pix0r), который скрыт / не скрыт перед скрытием или отображением контроллера вида на основе этого очень хорошего блоге.
Что касается контроллера вида, наконечник должен сделать его фоновый вид
clearColor
, тогда вид полупрозрачного наложения виден, и любые виды, добавленные в качестве подвидов в контроллере вида, находятся спереди и больше всего главное непрозрачно.
Я создал открытую библиотеку soruce MZFormSheetController представить лист модальной формы на дополнительном UIWindow. Вы можете использовать его для представления прозрачности модального контроллера вида, даже настроить размер представленного контроллера вида.
для iOS 8+ вы можете использовать
UIModalPresentationOverCurrentContext
стиль презентации для представил контроллер просмотра для легкого достижения желаемого поведения.UIViewController *viewController = [[UIViewController alloc] init]; viewController.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.9f]; viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; [self presentViewController:viewController animated:YES completion:nil];
Если Вам также нужна поддержка iOS 7-Проверьте этой теме.
вы можете добиться прозрачного / полупрозрачного эффекта модального вида, наложив прозрачную / полупрозрачную кнопку как на вид, так и на панель навигации.
вы можете получить доступ к панели навигации через свойство navigationBar UINavigationController.
Я обнаружил, что UIButton в отличие от UILabel будет ловить события мыши - следовательно, давая правильное модальное поведение.
Я нашел обходной путь для этого. Просто создайте 1X1 UIViewController и добавьте его в свой родительский контроллер вида. И показать прозрачную регулятора модальное представление в том, что для UIViewController.
on viewDidLoad;
self.dummyViewController = [[UIViewController alloc] init]; [личность.dummyViewController.вид setFrame:CGRectMake(0, 0, 1, 1)]; [личность.просмотр addSubView: self.dummyViewController.view];
когда вам нужно открыть transparentViewController;
[self.dummyViewController presentModalViewController: yourtransparentmodalviewcontroller animated: true];
Если вам нужен экран как крепится один, ниже код может помочь вам.
код:
MyViewController * myViewController = [[MyViewController alloc] initWithNibName:nibName bundle:nil]; UINavigationController * myNavigationController = [[UINavigationController alloc] initWithRootViewController: myViewController]; myNavigationController.modalPresentationStyle = UIModalPresentationPageSheet; [self presentModalViewController: myNavigationController animated:YES];