После всего волнения шаровых мета-шариков , рисования, чувствительного к давлению, и взвешивания слив с помощью 3D Touch , мы возвращаемся к чуть более пешеходному предмету: составному компоненту «иерархический селектор», использующему UIPickerView для навигации по категориям и UICollectionView для выбора элементов из этих категорий.
Этот компонент будет частью 3-й версии Nodality , моего приложения для обработки изображений на основе моего узла. В Nodality категории фильтра Core Image (такие как размытие ) будут категориями, а сами фильтры (такие как Gaussian Blur ) будут элементами.
В демонстрационном приложении я использую страны в качестве категорий и несколько их городов в качестве элементов. При нажатии на элемент города карта центрируется на выбранном городе. Я также добавил кнопку «назад» — просто чтобы доказать, что новый компонент может быть установлен программно.
Если выбранный элемент принадлежит категории, которая в данный момент не отображается, я добавляю маркер к названию категории.
Компонент имеет полезный заголовок FMHierarchicalSelector и доступен в моем репозитории GitHub здесь .
Внедрение FMHierarchicalSelector
Чтобы использовать FMHierarchicalSelector в вашем собственном проекте, вам потребуется делегат, который реализует FMHierarchicalSelectorDelegate. Этот протокол содержит три метода:
категории
func categoriesForHierarchicalSelector(hierarchicalSelector: FMHierarchicalSelector) -> [FMHierarchicalSelectorCategory]
Возвращает массив категорий (FMHierarchicalSelectorCategory). Категории — это просто строки, поэтому моя реализация для демонстрации выглядит так:
let categories: [FMHierarchicalSelectorCategory] = [
"Australia",
"Canada",
"Switzerland",
"Italy",
"Japan"].sort()
Предметы
func itemsForHierarchicalSelector(hierarchicalSelector: FMHierarchicalSelector) -> [FMHierarchicalSelectorItem]
Возвращает плоский массив всех элементов. Ваш тип элемента должен реализовывать FMHierarchicalSelectorItem, который включает в себя методы получения и установки для имени и категории элементов. Очевидно, что вы можете добавить любые дополнительные данные, которые вам нужны, поэтому для моего проекта я создал структуру Item, которая также имеет свойство координат типа CLLocationCoordinate2D.
Мои itemsForHierarchicalSelector () выглядит примерно так:
let items: [FMHierarchicalSelectorItem] = [
Item(category: "Australia", name: "Canberra", coordinate: CLLocationCoordinate2D(latitude: -35.3075, longitude: 149.1244)),
Item(category: "Australia", name: "Sydney", coordinate: CLLocationCoordinate2D(latitude: -33.8650, longitude: 151.2094)),
Отвечая на изменения
func itemSelected(hierarchicalSelector: FMHierarchicalSelector, item: FMHierarchicalSelectorItem)
Последняя функция в FMHierarchicalSelectorDelegate вызывается для делегата, когда пользователь выбирает новый элемент (город в случае демонстрации).
Аргумент item имеет тип FMHierarchicalSelectorItem, поэтому в моей реализации я пытаюсь преобразовать его в «Предмет», и в случае успеха я могу извлечь географические координаты выбранного города и соответствующим образом обновить свою карту:
func itemSelected(hierarchicalSelector: FMHierarchicalSelector, item: FMHierarchicalSelectorItem)
{
guard let item = item as? Item else
{
return
}
let span = MKCoordinateSpanMake(0.5, 0.5)
let region = MKCoordinateRegionMake(item.coordinate, span)
mapView.setRegion(region, animated: false)
history.append(item)
}
В заключении
Хотя визуальный дизайн FMHierarchicalSelector в значительной степени ориентирован на следующую версию Nodality, он предназначен для работы с любыми типами данных и поэтому является довольно универсальным компонентом, позволяющим пользователям перемещаться по большим наборам данных. FMHierarchicalSelector доступен по адресу