IOS 7 Прозрачный контроллер Modal View

Приложение App Store на iOS 7 использует эффект матового стекла, в котором можно увидеть вид сзади. Это использование API, встроенного в iOS 7, или это настраиваемый код. Я надеялся, что это будет первый, но я не вижу никаких очевидных ссылок в документации. Очевидные вещи, такие как (например, установка свойства alpha на модальном представлении), похоже, не имеют никакого эффекта.

Чтобы увидеть пример, откройте приложение App Store и нажмите кнопку в правом верхнем углу.

App Store home pageModal view in the App Store

Ответ 1

С выпуском iOS 8.0 нет необходимости получать изображение и смазывать его больше. Как отметил Andrew Plummer, вы можете использовать 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:

Как уже подчеркивалось, вы можете создать этот эффект:

  • Преобразование базового UIView в UIImage
  • Размытие UIImage
  • Установите UIImage в качестве фона вашего представления.

enter image description here


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

1. Создайте категорию UIView и добавьте следующий метод:

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

    return image;
}

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

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

Просто переопределил решение Себастьяна Ходжаса в Свифте:

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 Image Effect (я нашел повторное выполнение этого в 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)

Ответ 3

Я думаю, что это самое простое решение для модального контроллера представления, который накладывает все на приятное размытие (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];

Ответ 4

В iOS 7 SDK отсутствует API, который позволит вам "заморозить" контроллер подкладок.

То, что я сделал, - это визуализировать подстилающий вид изображения, которое я затем замаскировал и установить в качестве фона представление, которое будет представлено.

Apple является хорошим примером для этого: https://developer.apple.com/downloads/index.action?name=WWDC%202013

Выбранный проект называется iOS_RunningWithASnap

Ответ 5

Немного более простой способ добиться этого (на основе ответа Эндрю Пламмера) с помощью Interface Builder (также он устраняет побочный эффект, который появляется в ответе Эндрюса):

  • В IB добавьте визуальный эффект в свой контроллер просмотра под другими вашими представлениями;
  • Сделать верхние, нижние, левые, правые ограничения от визуального эффекта Просмотр в верхний (родительский) вид, установить все из них на 0;
  • Установить стиль размытия;
  • Добавьте код, в котором вы представляете свой новый внешний вид View Controller:

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

mainButtonViewController.view.backgroundColor = [UIColor clearColor];

fancyViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

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

Собственно, вторая и третья строки ОЧЕНЬ важны - иначе контроллер будет мигать, а затем станет черным.

Ответ 6

Так как 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, которое является первым видимым видом.

Ответ 7

Как сказал @rckoenes, для обеспечения этого эффекта не предусмотрена инфраструктура Apple. Но некоторые люди уже создали хорошие альтернативы, например, такие как:

https://github.com/JagCesar/iOS-blur/

Ответ 9

Я загрузил мой захват размытого контроллера вида на [GitHub] [1]. Он также поставляется с подклассом segue, поэтому вы можете использовать его в своих раскадровки.

Репозиторий: https://github.com/datinc/DATBlurSegue

Ответ 10

Быстрое и простое решение с поддержкой XIB, которую вы можете использовать для старых школьников https://github.com/cezarywojcik/CWPopup

Ответ 11

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

Это позволит вам как можно ближе имитировать размытый модальный вид appstore.

Ответ 12

Apple выпустила категорию UIImageEffect для этих эффектов. Эта категория должна быть добавлена ​​вручную в проект, и она поддерживает iOS7.

Ответ 13

Вы можете использовать UIToolbar в качестве фона. По умолчанию UIToolbar имеет высоту 50 пикселей. Добавьте ограничения автоматической компоновки на UIToolbar. Затем выберите ограничение по высоте и измените его.

Иерархия будет выглядеть так:

UIView -> clear colour for background.
- UIToolbar
- Other contents.