Я работаю над реализацией iOS версии существующего Kotlin Android приложения. Специфика c, которую я воспроизводю, представляет собой пошаговый рабочий процесс мастера.
Как я это сделал в Android
В Android, библиотеке , которую я использовал * У 1006 * был следующий процесс:
- Добавить "шаговый" вид к действию root и предоставить
StepAdapter
этому виду StepAdapter
контролирует количество шагов и возвращает каждый шаг по запросу по индексу. - Каждый шаг - это
Fragment
, реализующий интерфейс Step
, который обеспечивает ловушки для проверки и перехода между шагами.
В итоге я создал абстрактный тип Fragment
, который обеспечивает реализации по умолчанию для методов Step
:
abstract class StepFragment(private val index: Int) : Fragment(), Step {
...overriding some methods from Fragment
...implementing methods from Step
}
Каждый шаг Fragment
наследует этот класс, передавая жестко кодированный index
в конструктор StepFragment
. Шаги могут переопределить некоторые методы из StepFragment
, а некоторые из них также вызывают реализацию суперкласса (я использую аннотацию @CallSuper
, чтобы облегчить это). StepAdapter
создает и возвращает каждый из этих фрагментов.
Как я пытаюсь это сделать в iOS
Вернувшись в мир iOS / Swift, я обнаружил похожая библиотека , но все, что она предоставляет, это представление индикатора выполнения. Он не обрабатывает создание и отображение содержимого каждого шага, как Android. Мне нужно разобраться с этим сам.
Однако вы можете предоставить делегату степперу, который позволит вам подключаться к переходам (willSelectIndex, didSelectIndex, canSelectIndex и т. Д. c.). Я сделал root ViewController
делегатом для степпера. Это ViewController
имеет вид индикатора выполнения в верхней части и контейнер для каждого шага под индикатором выполнения. ViewController
каждого шага встроен в соответствующий контейнер. Чтобы контролировать переходы между шагами, я просто показываю и скрываю эти виды контейнера. Я понял эту часть.
Чего я не понял, так это как скопировать класс StepFragment
из Android Fragment
s в Swift ViewController
s. У меня следующие проблемы:
- Swift не имеет абстрактных классов (по некоторым причинам).
- Я не создаю экземпляр шага
ViewController
s; это обрабатывается внутри раскадровкой. Это означает, что я не могу предоставить индекс шага в конструкторе, как в Android. Абстрактное свойство было бы типичным способом обойти это, но (см. Выше) Swift не имеет абстрактных классов.
Я мог бы обойти эти проблемы несколькими способами:
- Вместо абстрактного класса я могу использовать протокол. Я могу указать требование, чтобы все классы, которые соответствуют протоколу, были
ViewController
с, но я не могу переопределить методы из ViewController
в протоколе (насколько я мог видеть). Я могу добавить расширение к протоколу, чтобы обеспечить функции реализациями по умолчанию, которые затем могут переопределить разработчики, и они могут даже вызывать исходные функции (используя (self as Protocol).func()
). Однако это кажется очень неуклюжим. - Вместо абстрактного класса я могу использовать обычный класс. Я могу добиться всего, чего хочу, за исключением того, что не могу добиться того, чтобы подкласс реализовывал абстрактные члены во время компиляции. Мне нужно было бы использовать что-то вроде
fatalError()
в базовом классе, который выбрасывает только во время выполнения. Это также кажется неуклюжим. - Я продолжаю слышать о шаблоне «делегат», и я думаю, что это хороший элегантный способ решить множество проблем «быстро», но я понятия не имею, как бы я используйте это здесь. Я думаю, что предпочел бы иметь возможность сделать это таким образом, чем два вышеуказанных.
TL; DR
Подводя итог моей проблеме, я ищу способ для нескольких " шаг "child ViewController
s", чтобы подключиться к рабочему процессу мастера, контролируемому родителем ViewController
. Они должны быть в состоянии выполнить некоторые (потенциально асинхронные c) логи c при выборе шага, перед переходами и даже переходами блоков. Я должен иметь возможность игнорировать некоторые из этих хуков, которые затем должны использовать реализацию по умолчанию.