Pop Up View пример

Задача

Итак, наша задача создать iOS приложение, в среде разработки Xcode,  в котором будет всплывающее окно —Pop Up View, при этом все что сзади этого окна будет затемняться. Подобный прием использован во многих приложениях, но я не смог найти информацию как именно это сделать — насколько нужно затемнять, сколько времени должна идти анимация и пр.

В итоге, я сделал этот Pop Up View на свой вкус. Читатели смогут самостоятельно изменить параметры всплывающего окна и подстроить их на свое усмотрение.

После выполнения задачи у нас получится такое приложение:

 

Создание проекта

В Xcode создайте новй проект, Single View Application и назовите его как нибудь — я назвал PopUpView. Из библиотеки объектов перетащите на имеющийся View Controller кнопку и установите текст кнопки «Показать». Установите ограничения для этой кнопки, чтобы она была размещена по центу контроллера. Это не обязательное условие, и вы можете разместить кнопку в Interface Builder Xcode как хотите. У меня получилось так:

Добавьте еще одни контроллер из библиотеки элементов Xcode.  Сразу добавьте файл, в котором будет описан класс нашего нового контроллера.

Можете создать файл вручную, в этом случае укажите наименование нового класса и то что наследуется от UIVewController. Либо Xcode создаст этот файл автоматически.

//
// proSwift.ru
//
// Swift 4

import UIKit

class PopUpViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Не забудьте в панели утилит справа присвоить контроллеру созданный клас

Добавление всплывающего окна

В редакторе интерфейса Xcode на вновь созданный контроллер добавьте View небольшого размера и разместите его по центру контроллера. Добавьте ограничения, измените цвет на ваш вкус. Я выбрал светло-светло-серый. На этот View следует добавить кнопку, изменить текст кнопки на «Закрыть».  Я поклонник закругленных углов, поэтому я добавил outlet для View,  назвал его MessageView. Вот как это выглядит у меня:

 

Обратите внимание, что в структуре View кнопка «Закрыть» внутри серого View. Также на скриншоте видна еще строка кода, которая закругляет углы, обращаясь через созданный на предыдущем шаге outlet. Как видите код я вызвал в методе viewDidLoad() контроллера PopUpVC.

//
// proSwift.ru
//
// Swift 4

    override func viewDidLoad() {
        super.viewDidLoad()
        messageView.layer.cornerRadius = 24
   }

 Вывод на экран

Итак, все предварительные приготовления сделаны, теперь давайте попробуем отобразить все безобразие, которое мы насоздавали. И первое что нужно сделать, это создать Action, т.е. метод, который будет вызываться при нажатии на кнопку «Показать».

 Далее следует добавить код, который покажет контролер PopUpViewController поверх корневого ViewController.  Этот код нужно добавить во вновь созданый метод

//
// proSwift.ru
//
// Swift 4

    @IBAction func showPopUp(_ sender: UIButton) {
        let popUpVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "popUpVCid") as! PopUpViewController // 1
        
        self.addChildViewController(popUpVC) // 2
        popUpVC.view.frame = self.view.frame  // 3
        self.view.addSubview(popUpVC.view) // 4
        
        popUpVC.didMove(toParentViewController: self) // 5
    }

Что тут у нас происходит:

  1. Мы получаем ссылку на PopUpViewController, причем получаем ссылку мы при помощи метода, который обращается к StoryBoard и находит контроллер, у которого идентификатор popUpVCid. ВНИМАНИЕ! Мы его еще не устанавливали, сделаем чуть ниже.
  2. Добавляем полученный контроллер PopUpViewController в качестве дочернего к ViewController.
  3. Размеры View нового контроллера мы устанавливаем равными размера View текущего контроллера.
  4. Непосредственно выводим на экран то,  как отображается PopUpViewController. Т.е. добавляем View PopUpViewController в стек той кучи View, которые уже есть.
  5. Вызываем метод делегата, чтобы сообщить всем делегатам, о том, что контроллер мы отобразили.

И прежде чем в первый раз запустить проект, нужно добавить идентификатор, о котором мы говорили на предыдущем шаге в пункте 1.

Только после этого можно запускать проект и нажимать на кнопку «Показать». Если все сделано правильно и мы ничего не забыли, то в симуляторе вы увидите следующее:

Закрываем окно

Для того чтобы закрыть всплывающее окно прежде всего нужно добавить Action на кнопку «Закрыть». Добавляйте кому как удобно  — провой кнопкой мыши, ctrl-перетягивание, или через панель утилит и вкладку связей. Это не имеет значение, Xcode заботливо соберет и скомпилирует все связи за нас.

Добавляем строку кода для удаления отображения контроллера PopUpVC во вновь сознанный Action.

//
// proSwift.ru
//
// Swift 4

    @IBAction func closePopUp(_ sender: UIButton) {
        self.view.removeFromSuperview()
    }

Можно запустить и посмотреть что получится. Обе кнопки должны работать.




 

Детали

Всю программную логику отображения и закрытия всплывающего окна мы создали. Теперь нужно доработать детали отображения

На этом этапе можно сделать необязательные добавления, чтобы в полной мене оценить эффект того, что мы будем делать дальше. Ничего сложного тут нет, просто нужно добавить несколько Label с сообщениями. Я добавлю на корневой контроллер (чтобы было видно запись через затемненный фон) и на серое View с текстом сообщения.

Затемнение фона

Для этого просто установим цвет у фона PopUpViewController в темный цвет и добавим фону прозрачности. Это следует произвести в том же методе, в котором мы меняли углы у серого View.

//
// proSwift.ru
//
// Swift 4

    override func viewDidLoad() {
        super.viewDidLoad()
        messageView.layer.cornerRadius = 24
        self.view.backgroundColor = UIColor.black.withAlphaComponent(0.75)
   }

Запустите проект и отобразите Pop Up контроллер:

Анимация

Для пущего эффекта добавим немного анимации. Необходимо добавить два метода, которые будут отвечать за появление окна и его убирание с экрана. Анимировать мы будем элементы PopUpViewController, поэтому добавлять методы мы будем именно ему. В Класс PopUpViewController после метода закрытия окна добавьте еще два метода:

//
// proSwift.ru
//
// Swift 4

    func moveIn() {
        self.view.transform = CGAffineTransform(scaleX: 1.35, y: 1.35)
        self.view.alpha = 0.0
        
        UIView.animate(withDuration: 0.24) {
            self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            self.view.alpha = 1.0
        }
    }
    
    func moveOut() {
        UIView.animate(withDuration: 0.24, animations: {
            self.view.transform = CGAffineTransform(scaleX: 1.35, y: 1.35)
            self.view.alpha = 0.0
        }) { _ in
            self.view.removeFromSuperview()
        }
    }

Думаю, эти два метода не вызовут вопросов.  Мы уже много раз разбирали принципы анимации. Но если необходимо, можно еще что нибудь новенькое санимировать.

Теперь нужно вызвать эти методы, и я думаю, читатели догадались где именно нужно их вызвать. В метод viewDidLoad() нудно добавить вызов метода moveIn(), а в метод closePopUp(_) закомментировать строку, которая убирает отображение с экрана. Вместо нее добавим вызов метода moveOut()

//
// proSwift.ru
//
// Swift 4

    override func viewDidLoad() {
        super.viewDidLoad()
        messageView.layer.cornerRadius = 24
        self.view.backgroundColor = UIColor.black.withAlphaComponent(0.75)
        
        moveIn()
   }
    
    @IBAction func closePopUp(_ sender: UIButton) {
        //self.view.removeFromSuperview()
        moveOut()
    }

Запустите проект и посмотрите конечный результат.

 

Код файлов контроллеров:

ViewController:

//
// proSwift.ru
//
// Swift 4

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func showPopUp(_ sender: UIButton) {
        let popUpVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "popUpVCid") as! PopUpViewController // 1
        
        self.addChildViewController(popUpVC) // 2
        popUpVC.view.frame = self.view.frame  // 3
        self.view.addSubview(popUpVC.view) // 4
        
        popUpVC.didMove(toParentViewController: self) // 5
    }
}

PopUpViewController:

//
// proSwift.ru
//
// Swift 4


import UIKit

class PopUpViewController: UIViewController {

    @IBOutlet weak var messageView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        messageView.layer.cornerRadius = 24
        self.view.backgroundColor = UIColor.black.withAlphaComponent(0.75)
        
        moveIn()
   }
    
    @IBAction func closePopUp(_ sender: UIButton) {
        //self.view.removeFromSuperview()
        moveOut()
    }
    
    func moveIn() {
        self.view.transform = CGAffineTransform(scaleX: 1.35, y: 1.35)
        self.view.alpha = 0.0
        
        UIView.animate(withDuration: 0.24) {
            self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            self.view.alpha = 1.0
        }
    }
    
    func moveOut() {
        UIView.animate(withDuration: 0.24, animations: {
            self.view.transform = CGAffineTransform(scaleX: 1.35, y: 1.35)
            self.view.alpha = 0.0
        }) { _ in
            self.view.removeFromSuperview()
        }
    }
}

Ссылка проекта на  GitHub

 




4 Comments on “Pop Up View пример

  1. Спасибо за урок. Правда, с обновлением Swift методы вроде toParentViewController переименованы: toParentViewController теперь просто toParent и с toChild то же самое случилось. Хорошо, что XCode об этом уведомляет.

    Спасибо большое за урок, хотелось бы видеть ещё статьи!

Добавить комментарий

Ваш адрес email не будет опубликован.

*

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.