Как представить контроллер модального представления, например, с помощью UIKit UIViewControllerTransitioningDelegate?

Я перехожу с UIKit на SwiftUI и все еще пытаюсь понять некоторые его части, особенно переходы между представлениями.

У меня есть ситуация, когда на экране отображается контроллер представления со списком, скажем, ElementsListViewController(), и при нажатии на элемент я хочу отобразить модальное окно с пользовательским интерфейсом/анимацией: появится непрозрачное наложение с анимацией альфа-значения, а белый модальный «лист» будет появляться снизу вверх.

Вот как это выглядит:

Как представить контроллер модального представления, например, с помощью UIKit UIViewControllerTransitioningDelegate?

С UIKit я бы использовал UIViewControllerAnimatedTransitioning для этого.

Теперь я хотел бы сделать то же самое со SwiftUI, но я потерялся, что делать именно здесь.

У меня пока так:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ElementsList()
        }
    }
}

struct ElementsList: View {
    @State var elements: [String] = (0..<100).map { "Element #\($0)" }

    var body: some View {
        List(elements, id: \.self) {
            Text($0)
                .onTapGesture {
                    // what to do here to display ModalView as I want to?
                }
        }
        .listStyle(PlainListStyle())
    }
}

struct ModalView: View {
    var body: some View {
        ZStack {
            Color.black.opacity(0.8)
            Color.white
                .cornerRadius(20.0)
                .padding(.top, 150)
        }
        .ignoresSafeArea()
    }
}

Каков мой лучший вариант здесь? спасибо за помощь

Создайте свой собственный и/или используйте UIViewControllerRepresentable. Это кажется сложнее, чем есть на самом деле, но я бы хотел, чтобы вы знакомы с UIKit, это всего лишь несколько дополнительных строк, чтобы заставить его работать со SwiftUI см. здесь для начала

lorem ipsum 17.05.2022 19:46

@loremipsum Спасибо за ответ! Я знаю, что мог бы легко сделать это с помощью UIViewControllerRepresentable, но я намерен сделать это на 100% SwiftUI, если это возможно, чтобы понять его как можно лучше!

Another Dude 17.05.2022 20:15

это невозможно сделать со стандартными ViewModifiers. Вы можете создать свой собственный, а также пользовательский ViewModifier и Binding<Bool>, но вы потеряете свайп, особенно свайп с List. DragGesture будет мешать перетаскиванию List или ScrollView

lorem ipsum 17.05.2022 20:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
19
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ну, такой встроенной гибкости нет, скажем, в стандартном .sheet, но ее можно очень быстро реализовать на заказ.

Вот простая демонстрация (Xcode 13.3/iOS 15.4)

demo

Основная часть:

struct ElementsList: View {
// ...
        ModalView(isPresented: $isModal) {
            List(elements, id: \.self) {


struct ModalView<V: View>: View {
    @Binding var isPresented: Bool
// ...
        ZStack {
            content()
            ZStack {
                VStack {
                    if isPresented {
                        Color.black.opacity(0.8)
                            .transition(.opacity)
                    }
                }.animation(.easeInOut(duration: 0.25), value: isPresented)


Полный тестовый код в проекте находится здесь

Спасибо @Аспери!

Another Dude 17.05.2022 22:58

Другие вопросы по теме

SwiftUI: как сделать так, чтобы представление исчезало при скольжении вверх?
SwiftUI: как создать собственный переход SwiftUI в зависимости от объекта состояния?
Как заполнить все возможные столбцы в фрейме данных с помощью r data.table?
Поведение перехода оператора SwiftUI Switch не соответствует ожидаемому
Как добавить заголовок вторичной строки в выходную таблицу со встроенным реактивным объектом?
Как добавить реактивный объект в заголовок вторичного столбца в выходной таблице?
Как изменить этот код data.table, чтобы отображались переходы баланса вместо переходов частоты событий?
Как отформатировать таблицу с дополнительными заголовками столбцов и строк, включая вертикальное выравнивание и реактивные входы?
Как создать таблицу, измеряющую переходы элементов за календарные периоды?
Как изменить ширину справа налево, а не слева направо по умолчанию?