簡體   English   中英

SwiftUI 和 Swift 5.7:View 協議和不透明類型問題

[英]SwiftUI and Swift 5.7: Issue with View protocol and Opaque Types

當我嘗試從方法返回符合 View 協議的不同自定義視圖時出現編譯錯誤。 這是一個描述該問題的簡單示例。

我希望有一個方法可以根據枚舉情況返回不同的自定義視圖。 當我嘗試實現這一目標時,我得到不同的編譯錯誤:

    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方法拋出以下編譯錯誤: Function 聲明了一個不透明的返回類型“some View”,但其主體中的返回語句沒有匹配的底層類型

方法getAnyView 可以編譯,但是當我將其調用為 NavigationLink 的目標時出現以下錯誤:類型“任何視圖”不能符合“視圖”

我正在學習 Swift 5.7 中的 SwiftUI 和新的 generics 功能。 我相信我正在尋找的行為可以實現。 任何幫助或指導將不勝感激,在此先感謝!

這就是如何實現您正在嘗試做的事情。

  1. @ViewBuilder標記getSomeView() 這使它像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()
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM