SwiftUI и Swift 5.7: проблема с протоколом просмотра и непрозрачными типами

У меня возникает ошибка компиляции, когда я пытаюсь вернуть из метода разные пользовательские представления, соответствующие протоколу представления. Вот простой пример, описывающий проблему.

Я хочу иметь метод, который возвращает другое пользовательское представление на основе случая перечисления. Когда я пытаюсь добиться этого, я получаю разные ошибки компиляции:

          enum AppScreen: String, CaseIterable {
        case home
        case detail
    }
    
    struct ContentView: View {
        var body: some View {
            NavigationView {
                List {
                    ForEach(AppScreen.allCases, id: \.self) { screen in
                        NavigationLink(destination: getSomeView(screen)) {
                            Text(screen.rawValue)
                        }
                    }
                }
                List {
                    ForEach(AppScreen.allCases, id: \.self) { screen in
                        NavigationLink(destination: getAnyView(screen)) {
                            Text(screen.rawValue)
                        }
                    }
                }
            }
        }
    
        private func getSomeView(_ screen: AppScreen) -> some View {
            switch screen {
            case .home:
                return HomeView()
            case .detail:
                return DetailView()
            }
        }
        
        private func getAnyView(_ screen: AppScreen) -> any View {
            switch screen {
            case .home:
                return HomeView()
            case .detail:
                return DetailView()
            }
        }
    }

Метод getSomeView выдает следующую ошибку компиляции: Функция объявляет непрозрачный тип возвращаемого значения «некоторый вид», но операторы возврата в ее теле не имеют соответствующих базовых типов.

Метод getAnyView компилируется, но я получаю следующую ошибку, когда вызываю его в качестве места назначения для NavigationLink: Тип «любой вид» не может соответствовать «Вид»

Я изучаю SwiftUI и новые функции дженериков из Swift 5.7. Я считаю, что поведение, которое я ищу, может быть достигнуто. Любая помощь или руководство будут оценены, спасибо заранее!

1 ответ

Вот как добиться того, что вы пытаетесь сделать.

  1. ОтметкаgetSomeView()с@ViewBuilder. Это заставляет его работать какvar bodyкоторый также являетсяViewBuilderпозволяет создавать различные типы представлений.
  2. Удалитьreturnзаявления.

Вот отдельный пример, основанный на вашем исходном коде:

      enum AppScreen: String, CaseIterable {
    case home
    case detail
}

struct HomeView: View {
    var body: some View {
        Text("HomeView")
    }
}

struct DetailView: View {
    var body: some View {
        Text("DetailView")
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                ForEach(AppScreen.allCases, id: \.self) { screen in
                    NavigationLink(destination: getSomeView(screen)) {
                        Text(screen.rawValue)
                    }
                }
            }
        }
    }

    @ViewBuilder
    private func getSomeView(_ screen: AppScreen) -> some View {
        switch screen {
        case .home:
            HomeView()
        case .detail:
            DetailView()
        }
    }
}
Другие вопросы по тегам