Как выбрать несколько вещей в пользовательском интерфейсе

После нескольких недель перерыва в использовании контента SwiftUI я вернулся! В этой статье мы рассмотрим, как создать многосегментный сборщик. Это может быть полезно для выбора продолжительности времени (например, один день, четыре недели и т. Д.), Что было моим вариантом использования. Это конечный продукт:

Давайте сначала определим простое средство выбора одного сегмента в SwiftUI:

Давайте быстро рассмотрим это:

  1. Средству выбора SwiftUI требуется какой-то data (т.е. какие значения для средства выбора). Ему также нужны state или binding, которые информируют текущее выбранное значение.
  2. SwiftUI делает объявление средства выбора относительно простым. Первый аргумент - это метка средства выбора, а второй (selection) - привязка к текущему выделению. Последний аргумент - это закрытие, которое создает серию просмотров. Каждое представление - это выбираемое значение.
  3. Внутри средства выбора мы создаем серию представлений с помощью ForEach. Обратите внимание, что вместо перебора самого data мы перебираем индексы. Это нормально, пока количество элементов в ForEach не меняется. Если это так, рассмотрите возможность согласования пунктов в data с Identifiable.
  4. Мы отображаем значение с помощью Text и присваиваем ему tag значение индекса. Это означает, что каждый экземпляр Text связан с индексом в массиве. Это работает с аргументом selection для SwiftUI, чтобы определить, какой элемент отображать как текущий выбор.

Создание нескольких сегментов

Это было довольно стандартно, но как мы можем начать определять несколько сегментов для средства выбора? На мой взгляд, всегда лучше начинать сначала с модели представления. Таким образом, мы можем четко описать, как выглядят наши входящие данные, и соответственно создать наше представление:

Наша модель представления имеет единственное свойство segments, которое представляет собой массив кортежей. Каждый кортеж представляет собой один сегмент в средстве выбора. Каждый кортеж состоит из:

  1. Ярлык String.
  2. Привязка к выделению. В этом случае мы используем индекс выбора как целое число, но вы можете использовать любую привязку, которую сочтете подходящей, изменив псевдоним типа.
  3. Массив значений для определенного сегмента. Мы определили, что они относятся к типу String, но, опять же, псевдоним типа может использоваться для вашего варианта использования.

Теперь мы можем определить представление:

Отлично! Это именно то, что мы хотим. Пойдем по обзору. Обратите внимание, что мы объявляем набор средств выбора, расположенных по горизонтали, используя HStack:

  1. Чтобы мы могли определять несколько сегментов, мы должны соответствующим образом определить размер каждого средства выбора. GeometryReader дает нам размер родительского представления. Затем мы можем использовать это для кадрирования каждого Picker соответственно.
  2. Как уже упоминалось, для горизонтального расположения сборщиков мы используем HStack.
  3. Мы перебираем различные сегменты средства выбора и определяем средство выбора для каждого сегмента, используя ForEach. Обратите внимание, что определение для каждого отдельного средства выбора такое же, как в нашем первоначальном примере средства выбора из одного сегмента.
  4. Мы используем .frame(...) для определения размера каждого средства выбора до соответствующей ширины, которая является родительской шириной, деленной на количество средств выбора.
  5. Ключевым моментом здесь является использование .clipped(). Если мы не будем использовать модификатор, вы увидите, что линии средства выбора будут перекрываться. clipped() будет следить за тем, чтобы каждое средство выбора не выходило за пределы каждого представления.

И готово: многосегментные средства выбора в SwiftUI. Посетите площадку GitHub со всем кодом для многосегментного сборщика.