Одними из самых востребованных классов в UIKit до выхода iOS версии 8 являлись UIAlertView и UIActionSheet. Наверное, каждый разработчик приложений под мобильную платформу от Apple рано или поздно сталкивался с ними. Показ сообщений или меню выбора действий — это неотъемлемая часть практически любого пользовательского приложения. Для работы с этими классами, а точнее для обработки нажатий кнопок, программисту требовалось реализовывать в своем классе методы соответствующего делегата — UIAlertViewDelegate или UIActionSheetDelegate (если не требовалось чего-то сверх, то достаточно было реализовать метод clickedButtonAtIndex). На мой взгляд это очень неудобно: если внутри объекта создавалось несколько диалоговых окон с разными наборами действий, то их обработка все равно происходила в одном методе с кучей условий внутри. С выходом 8 версии iOS в составе UIKit появился класс UIAlertController, который пришел на смену UIAlertView и UIActionSheet. И одной из его главных отличительных черт является то, что вместо делегатов он использует блочный подход:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Hello" message:@"Habr!" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"Action" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// код обработчика кнопки
}]];
Такой подход позволяет писать более структурированный и логичный код. Отныне программисту больше не требуется разделять создание диалогового окна и обработку событий — UIAlertController устраняет это недоразумение, но одновременно с этим привносит историческую несправедливость из-за невозможности использования в iOS 7 и более ранних версиях. Решить эту проблему можно несколькими способами:
- Не обращать внимание на UIAlertController и продолжать использовать устаревшие UIAlertView и UIActionSheet.
- Использовать нестандартные диалоговые окна. Программист либо пишет собственную реализацию, что приводит к увеличению временных затрат, либо подключает сторонние компоненты (например, SIAlertView), использование которых имеет ряд недостатков:
- программные модули с хорошей поддержкой можно пересчитать по пальцам (зачастую их создатели быстро забрасывают это неблагодарное дело);
- если в проекте используются несколько компонентов от разных разработчиков, то при их взаимодействии могут возникать проблемы (редко, но это возможно).
- Проверять версию iOS и создавать либо UIAlertController, либо UIAlertView или UIActionSheet.
Последний вариант наиболее логичен, и большинство разработчиков, я уверен, выбрали бы именно его, но данный метод имеет существенный недостаток — условие проверки версии операционной системы придется писать каждый раз, когда потребуется отобразить диалоговое окно. Столкнувшись с этим на практике, я создал специальный класс-обертку UIAlertDialog, который позволяет забыть об этой проблеме.
Читать полностью »