Напівпрозорий модальний контролер iOS 7


77

Додаток App Store на iOS 7 використовує ефект матового скла, де можна побачити вигляд ззаду. Це за допомогою API, вбудованого в iOS 7, чи це власний код. Я сподівався, що це буде перше, але я не бачу жодних очевидних посилань у документації. Очевидні речі, такі як (наприклад, встановлення властивості альфа в модальному поданні), здається, не мають жодного ефекту.

Щоб побачити приклад, відкрийте додаток App Store і натисніть кнопку вгорі праворуч.

Домашня сторінка App Store Модальний вигляд в App Store


Мені подобається ваше запитання
Tà Truhoada

@Ian - ви повинні прийняти відповідь Себастьяна
Хохаса

Відповіді:


132

З виходом iOS 8.0 немає необхідності отримувати зображення та розмивати його більше. Як зазначив Ендрю Пламмер , ви можете використовувати UIVisualEffectView з UIBlurEffect .

UIViewController * contributeViewController = [[UIViewController alloc] init];
UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
beView.frame = self.view.bounds;

contributeViewController.view.frame = self.view.bounds;
contributeViewController.view.backgroundColor = [UIColor clearColor];
[contributeViewController.view insertSubview:beView atIndex:0];
contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:contributeViewController animated:YES completion:nil];

Рішення, яке працює до iOS 8

Я хотів би продовжити відповідь rckoenes:

Як підкреслювалося, ви можете створити цей ефект, виконавши:

  1. Перетворити базовий UIView на UIImage
  2. Розмийте UIImage
  3. Встановіть UIImage як фон вашого перегляду.

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


Звучить багато роботи, але насправді виконується досить прямо:

1. Створіть категорію UIView та додайте такий спосіб:

-(UIImage *)convertViewToImage
{
    UIGraphicsBeginImageContext(self.bounds.size);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

2. Створіть зображення поточного вигляду і розмийте його за допомогою категорії Image Effect від Apple ( завантажити )

UIImage* imageOfUnderlyingView = [self.view convertViewToImage];
imageOfUnderlyingView = [imageOfUnderlyingView applyBlurWithRadius:20
                             tintColor:[UIColor colorWithWhite:1.0 alpha:0.2]
                 saturationDeltaFactor:1.3
                             maskImage:nil];

3. Встановіть його як фон вашого накладання.

-(void)viewDidLoad
{
   self.view.backgroundColor = [UIColor clearColor];
   UIImageView* backView = [[UIImageView alloc] initWithFrame:self.view.frame];
   backView.image = imageOfUnderlyingView;
   backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
   [self.view addSubview:backView];
}

2
developer.apple.com/downloads/download.action?path=wwdc_2013/… - Пряме посилання на категорію ефектів зображення
OneManBand

@OneManBand Додав посилання. Дякую!
Себастьян Хохас,

3
Це буде вести себе не так, як контролер модального перегляду App Store, який насправді динамічно розмиває те, що знаходиться внизу, включаючи анімовані додатки.
Vadoff

2
Починаючи з iOS 8, нарешті є прямий спосіб досягти цього ефекту за допомогою UIModalPresentationOverCurrentContext. Дивіться відповідь Ендрю Пламмера, mxcl та Андрія Костянтинова нижче.
Renfei Song

Це не залишається розмитим? За допомогою методу iOS 8 фон розмивається при переході та прозоро відображає перший контролер перегляду, але модальний контролер перегляду стає чорним після повного завантаження.
Крашалот

25

Щойно реалізовано рішення Себастьяна Хохаса в Swift:

1. Створіть розширення UIView і додайте такий спосіб:

extension UIView {
    func convertViewToImage() -> UIImage{
        UIGraphicsBeginImageContext(self.bounds.size);
        self.drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext();

        return image;
    }
}

2. Створіть зображення поточного вигляду та розмийте його, використовуючи Ефект зображення Apple (я знайшов його повторну реалізацію в Swift тут: SwiftUIImageEffects

var imageOfUnderlyingView = self.view.convertViewToImage()
imageOfUnderlyingView = imageOfUnderlyingView.applyBlurWithRadius(2, tintColor: UIColor(white: 0.0, alpha: 0.5), saturationDeltaFactor: 1.0, maskImage: nil)!

3. Встановіть його як фон вашого накладання.

let backView = UIImageView(frame: self.view.frame)
backView.image = imageOfUnderlyingView
backView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)
view.addSubview(backView)

15

Я думаю, що це найпростіше рішення для модального контролера перегляду, який накладає все на гарне розмиття (iOS8)

    UIViewController * contributeViewController = [[UIViewController alloc] init];

    UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *beView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    beView.frame = self.view.bounds;

    contributeViewController.view.frame = self.view.bounds;
    contributeViewController.view.backgroundColor = [UIColor clearColor];
    [contributeViewController.view insertSubview:beView atIndex:0];
    contributeViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

    [self presentViewController:contributeViewController animated:YES completion:nil];

1
Здається, накладення буде додано на верхній шар вигляду
c9s

1
Це не залишається розмитим? За допомогою методу iOS 8 фон розмивається при переході та прозоро відображає перший контролер перегляду, але модальний контролер перегляду стає чорним після повного завантаження. - Crashalot зараз редагує
Crashalot

@Crashalot Ви змінювали будь-які налаштування, наприклад, зміну UIModalPresentationOverCurrentContext на повноекранний?
Ендрю Пламмер,

1
Щоб додати @Crashalot, якщо ви не використовуєте цей модальний стиль презентації, він перестає "показувати" VC знизу після того, як модаль піднімається, отже, він стає "чорним" (нічого знизу)
Ендрю Пламмер

12

У iOS 7 SDK не існує API, який дозволить вам «заморозити» контролер подання, що лежить нижче.

Те, що я зробив, - це відобразити нижній вигляд зображення, яке я потім заморозив і встановив як тло поданий вигляд.

Apple наводить для цього хороший приклад: https://developer.apple.com/downloads/index.action?name=WWDC%202013

Проект, який ви хочете, називається, iOS_RunningWithASnap


і як ти можеш утримувати задній ViewController, поки модаль не працює? у моєму випадку задній ВК зникає ..
Жоао Нунес

Ні, оскільки задній viewController - це просто матове зображення на модальному контролері перегляду.
rckoenes

10

Трохи спрощений спосіб досягти цього (на основі відповіді Ендрю Пламмера) за допомогою Interface Builder (також він усуває побічний ефект, який з’являється у відповіді Ендрюса):

  • У IB додайте Visual Effect View до вашого View Controller під іншими переглядами;
  • Зробіть обмеження верхнього, нижнього, лівого, правого від подання Visual Effect до перегляду зверху (батьківського), встановіть для них усі значення 0;
  • Встановити стиль розмиття;
  • Додайте код, де ви представляєте свій новий вишуканий контролер перегляду:

UIViewController *fancyViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"yourStoryboardIDFOrViewController"];

fancyViewController.view.backgroundColor = [UIColor clearColor];
fancyViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:fancyViewController
                   animated:YES
                 completion:nil];

Насправді, другий і третій рядки ДУЖЕ важливі - інакше контролер буде блимати, а потім почорніє.


Що таке mainButtonViewController?
christijk

@christijk це має бути fancyViewController (це зараз). Дякую, що вказали.
Андрій Костянтинов

9

З iOS 8 це працює:

        let vc = UIViewController()
        vc.view = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
        vc.modalPresentationStyle = .OverFullScreen

        let nc = UINavigationController(rootViewController: vc)
        nc.modalPresentationStyle = .OverFullScreen

        presentViewController(nc, animated: true, completion: nil)

Ключ - .OverFullScreenпрапор і забезпечення того, щоб viewControllers мали розмиття UIVisualEffectView, що є першим видимим видом.




5

Я завантажив свій знімок контролера розмитого перегляду на [GitHub] [1]. Він також постачається з підкласом segue, щоб ви могли використовувати його у своїх раскадровках.

Сховище: https://github.com/datinc/DATBlurSegue


Презентація подання з анімацією та підтримка UIToolbar view app store store безпечна?
Brad Goss

Чи працює це, якщо контролер подання представлення є контролером навігації ??
Девід Ернандес,


5

Замість того, щоб представляти viewController як modalView, ви можете додати його як дочірній viewController і створити власну анімацію. Тоді вам потрібно буде лише змінити подання за замовчуванням viewController на UIToolBar у viewDidLoad.

Це дозволить вам якомога ближче імітувати розмитий модальний вигляд магазину додатків.



1

Ви можете використовувати панель UITool як тло. За замовчуванням панель UITool має висоту 50 пікселів. Додайте обмеження автоматичного розміщення на панелі UITool. Потім виберіть обмеження висоти та змініть його.

Ієрархія буде виглядати так:

UIView -> clear colour for background.
- UIToolbar
- Other contents.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.