如何在Swift UI中从函数返回View类型

27

我希望你能为我的应用程序创建一个相对优雅的导航系统。下面是一种试图返回 View 类型的函数。但是,这段代码无法编译通过:

    func getView(view: String) -> View {
        switch view {
        case "CreateUser":
            return CreateNewsView()
        default:
            return nil
        }
    }

上述结果导致编译错误:Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

感谢您的帮助。


以上编译错误: 协议“View”只能被用作泛型约束,因为它具有Self或相关类型的要求 - James
5个回答

53
截至Swift 5.3,@hồng-phúc的答案在某种程度上是正确的,只需要明确添加@ViewBuilder属性。
@ViewBuilder func getView(view: String) -> some View {
    switch view {
    case "CreateUser":
        Text(view)
    case "Abc":
        Image("Abc")
    default:
        EmptyView()
    }
}

侧记:请避免使用字符串常量,最好使用枚举。


1
哇塞,看起来很不错啊!我更新了这个答案,并且假设你正在使用最新的Swift UI版本 :) - James
@James 非常感谢,很高兴听到这个消息!是的,正在使用最新的SwiftUI :) - Frederik Winkelsdorf

6
我使用 AnyView() 包装器解决了这个问题:
func getView(view: String?) -> AnyView {
        switch view {
        case "CreateUser":
            return AnyView(CreateNewsView())
        default:
            return AnyView(EmptyView())
        }
    }

4
根据苹果公司的建议,对于SwiftUI的优化来说,使用AnyView是一种不好的做法。 - eharo2

2
制作 AnyView() 包装器。
func getView(view: String?) -> AnyView {
     
   if view == "CreateUser" {
       return AnyView(CreateNewsView())
   }
    
   return AnyView(EmptyView())
        
}

根据苹果的建议,对于SwiftUI优化来说,使用AnyView是一种不良实践。 - eharo2

0

你应该返回某个 View

示例:

func getView(view: String) -> some View {
     return YourView()
}

关于某些视图的更多细节,请查看this


4
еҸӘжңүеҪ“getViewж–№жі•жҖ»жҳҜиҝ”еӣһзӣёеҗҢзҡ„и§Ҷеӣҫе…·дҪ“зұ»еһӢпјҲеңЁзј–иҜ‘ж—¶е·ІзҹҘпјүж—¶пјҢиҝҷдёӘж–№жі•жүҚиғҪиө·дҪңз”ЁгҖӮдҪҶиҝҷдёҚжҳҜеҺҹеё–дҪңиҖ…жғіиҰҒзҡ„пјҢеӣ дёәд»–иҜ•еӣҫдҪҝз”ЁswitchиҜӯеҸҘе°Ҷеӯ—з¬ҰдёІиҪ¬жҚўдёәи§ҶеӣҫгҖӮ - New Dev
那么我们的意思是,添加@ViewBuilder是强制性的吗? - nyxee

-1
我使用扩展.eraseToAnyView()来使得带有一些视图的函数更加简单:
extension View {
      public function eraseToAnyView () -> AnyView {
          AnyView (on its own)
      }
}

最终的解决方案将会是这样的:
func getView (view: String?) -> AnyView {
         if view == "CreateUser" {
         return CreateNewsView().eraseToAnyView()
     }
         return EmptyView().eraseToAnyView()
}

我认为这是最简洁的解决方案。


2
根据苹果的建议,对于SwiftUI优化来说,使用AnyView是一种不良实践。 - eharo2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接