Как и радиокнопки и флажки , iOS не предоставляет встроенный элемент управления «выпадающим», как это обычно бывает на других платформах. Исторически, было возможно эмулировать этот тип управления, используя контроллер popover; однако до недавнего времени эта опция была доступна только на устройствах iPad и iPhone 6+ в горизонтальной ориентации. Начиная с iOS 9, теперь всплывающие окна можно использовать на любом устройстве с поддержкой iOS, что позволяет разработчикам использовать эту популярную абстракцию независимо от форм-фактора или ориентации устройства.
Эта статья иллюстрирует реализацию простого раскрывающегося списка, который позволяет пользователю указать цвет фона для представления. Доступ к списку можно получить, нажав кнопку «Цвет» на панели навигации приложения:
Реализация
Основное представление в приложении управляется классом с именем SelectionViewController
, который представлен в контроллере навигации. Элемент кнопки правой панели контроллера, помеченный «Цвет», обеспечивает доступ к раскрывающемуся списку. В viewDidLoad
методе SelectionViewController
создает элемент кнопки панели и назначает метод обработчика действия, который будет вызываться при касании элемента. Он также инициализирует экземпляр ColorPickerViewController
класса контроллера, который будет использоваться для представления пользователю списка вариантов цвета:
class SelectionViewController: UIViewController, UIPopoverPresentationControllerDelegate, UITableViewDelegate {
let colorPickerViewController = ColorPickerViewController()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.whiteColor()
title = "Color Picker"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Color", style: UIBarButtonItemStyle.Plain, target: self, action: "showColorPicker")
colorPickerViewController.modalPresentationStyle = .Popover
colorPickerViewController.tableView.delegate = self
}
func showColorPicker() {
...
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
...
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
...
}
}
showColorPicker
Метод вызывается в ответ на кране на кнопку «Color». Это определяется следующим образом:
func showColorPicker() {
let colorPickerPresentationController = colorPickerViewController.presentationController as! UIPopoverPresentationController
colorPickerPresentationController.barButtonItem = navigationItem.rightBarButtonItem
colorPickerPresentationController.backgroundColor = UIColor.whiteColor()
colorPickerPresentationController.delegate = self
presentViewController(colorPickerViewController, animated: true, completion: nil)
}
Сначала метод получает ссылку на контроллер представления контроллера представления палитры цветов и приводит его к экземпляру UIPopoverPresentationController
. Так как модальный стиль представления контроллера представления палитры цветов был установлен на UIModalPresentationStyle.Popover
in viewDidLoad
, это допустимый актерский состав.
Затем, метод связывает контроллер представления средства выбора цветов с элементом кнопки правой панели контроллера представления выбора (кнопка «Цвет»), гарантируя, что стрелка всплывающего окна будет указывать на кнопку. Затем он устанавливает белый цвет фона контроллера презентации, чтобы стрелка соответствовала табличному представлению, когда оно отображается во всплывающем окне. Наконец, он устанавливает сам контроллер представления выбора в качестве делегата контроллера представления. Это позволяет контроллеру принудительно отображать палитру цветов в виде фактического всплывающего окна, а не представления по умолчанию для текущего устройства (которое может быть полноэкранным, если пользователь работает на устройстве с горизонтальным ограничением, таком как iPhone в портретная ориентация, например).Это делается путем возврата UIModalPresentationStyle.None
из adaptivePresentationStyleForPresentationController:
метода UIPopoverPresentationControllerDelegate
:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
Наконец, showColorPicker
представлен контроллер вида палитры цветов, в результате чего всплывающее окно появляется на экране.
ColorPickerViewController
Класс обеспечивает фактическое содержание для выпадающего зрения выбора. Это реализовано следующим образом:
class ColorPickerViewController: UITableViewController {
override func loadView() {
view = LMViewBuilder.viewWithName("ColorPickerView", owner: self, root: nil)
}
override func viewWillAppear(animated: Bool) {
tableView.layoutIfNeeded()
preferredContentSize = tableView.contentSize
}
}
ColorPickerViewController
использует инфраструктуру MarkupKit, чтобы упростить конструкцию своего представления. Разметка для представления определяется следующим образом:
<LMTableView style="plainTableView" estimatedSectionHeaderHeight="0" estimatedSectionFooterHeight="0">
<?sectionSelectionMode singleCheckmark?>
<UITableViewCell textLabel.text="Red" value="#ff0000"/>
<UITableViewCell textLabel.text="Yellow" value="#ffff00"/>
<UITableViewCell textLabel.text="Green" value="#00ff00"/>
<UITableViewCell textLabel.text="Blue" value="#0000ff"/>
<UITableViewCell textLabel.text="Purple" value="#ff00ff"/>
</LMTableView>
Сначала он объявляет экземпляр предоставленного LMTableView
MarkupKit подкласса, UITableView
который облегчает определение содержимого статического табличного представления. Он устанавливает режим выбора первого (и единственного) раздела табличного представления на «singleCheckmark», что гарантирует, что за один раз будет выбрана только одна строка. Он также устанавливает нулевую оценку заголовка раздела и высоты нижнего колонтитула таблицы, чтобы гарантировать, что представление не выделяет никакого начального или конечного пространства для верхнего или нижнего колонтитула. Наконец, он объявляет ячейки, которые представляют параметры цвета. Используя value
свойство, добавленное UITableViewCell
MarkupKit, оно связывает шестнадцатеричное значение цвета с каждой ячейкой. Это значение будет использовано позже для установки цвета фона основного вида.
ColorPickerViewController
переопределяет, loadView
чтобы загрузить определение представления из разметки. Он также переопределяет viewWillAppear:
вызов layoutIfNeeded
своего табличного представления, а затем устанавливает собственный предпочтительный размер содержимого, соответствующий размеру содержимого табличного представления. Этот шаг важен, поскольку он позволяет автоматически изменять размер всплывающего окна в соответствии с размером содержимого табличного представления.
SelectionViewController
Реализует tableView:didSelectRowAtIndexPath:
ответ на ввод пользователя в табличном представлении палитры цветов:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
self.view.backgroundColor = LMViewBuilder.colorValue(cell!.value as! String)
dismissViewControllerAnimated(true, completion: nil)
}
Сначала код получает экземпляр для выбранной ячейки и получает ассоциированное с ним шестнадцатеричное значение цвета. Затем он вызывает colorValue:
метод LMViewBuilder
для преобразования шестнадцатеричного значения в экземпляр UIColor
, который он устанавливает в качестве значения цвета фона представления. Наконец, он отклоняет поповер.
Резюме
Эта статья продемонстрировала реализацию простого выпадающего списка с использованием контроллера представления popover. Обратите внимание, что хотя в примере использовался MarkupKit для упрощения реализации всплывающего окна, это не является строго обязательным. Например, a ColorPickerViewController
с пользовательским делегатом для обработки уведомлений о выборе будет работать так же хорошо, хотя и с немного большими усилиями и кодом.
Для получения дополнительной информации о MarkupKit, посетите сайт проекта GitHub . Дополнительные примеры смотрите в вики проекта .