简体   繁体   English

如何将视图添加为结构变量?

[英]How can I add a View as a struct variable?

I am looping through an array of Models and I want a different navigation destination for each one.我正在遍历一系列模型,我希望每个模型都有一个不同的导航目的地。 What is the best approach to that?最好的方法是什么? Here is the model这是model

struct HomePageGridItem: Identifiable {
    var id: Int
    var image: String
    var title: String
    var desc: String
}

And here is what I get when I try to add a destination这是我尝试添加目的地时得到的结果错误

I don't know what I'm missing here.我不知道我在这里错过了什么。

I'd agree that you shouldn't do this - the view should handle routing, whereas the model should inform routing.我同意你不应该这样做——视图应该处理路由,而 model 应该通知路由。

However, for your learning, it may be useful to understand a potential solution and what the error you're getting means - it comes up a lot in SwiftUI development.但是,对于您的学习,了解潜在的解决方案以及您遇到的错误意味着什么可能很有用 - 它在 SwiftUI 开发中经常出现。

Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

This error is displayed when the protocol in question ( View in this case), has an associated type defined internally, and you have not set a requirement for what this associated type should be.当相关协议(在本例中为View )具有内部定义的关联类型,并且您尚未设置该关联类型应该是什么的要求时,将显示此错误。 An example of a protocol with an associated type might be the Identifiable protocol...具有关联类型的协议示例可能是可Identifiable协议...

protocol Identifiable {
    associatedtype ID
    var id: ID { get set }
}

As you can see, there is an associated type defined - ID .如您所见,定义了一个关联类型 - ID This is a generic, meaning it can take on any form as needed for this protocol's use.这是一个通用的,这意味着它可以根据该协议的使用需要采用任何形式。 In each use of the protocol, the associatedtype (or generic) can only be defined upon initialization of the conforming object OR in your case, the declaration of a variable.在协议的每次使用中,关联类型(或泛型)只能在符合 object 的初始化时定义,或者在您的情况下是变量声明。 An example implementation of Identifiable might assign ID as type String . Identifiable的示例实现可能会将ID分配为类型String In that case, the id variable would be of type String .在这种情况下, id变量将是String类型。

As stated, the protocol in your situation is View .如前所述,您所处情况的协议是View It's definition looks something like this...它的定义看起来像这样......

protocol View {
    associatedtype Body
    var body: Body
}

The generic in this case is Body , which must be defined upon definition of the View .在这种情况下,泛型是Body ,它必须在定义View时定义。 Read more about protocols with associated types and their uses here:在此处阅读有关具有关联类型的协议及其用途的更多信息:

https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID189 https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID189

In your case, you must define your property destination as a concrete implementation of protocol View , because the associated type must be static for the definition of your variable.在您的情况下,您必须将属性destination定义为协议View的具体实现,因为对于变量的定义,关联类型必须是 static。 One useful concrete implementation of View is AnyView . View的一个有用的具体实现是AnyView Your model would look like this...你的 model 看起来像这样......

struct HomePageGridItem: Identifiable {
    var id: Int
    var image: String
    var title: String
    var desc: String
    var destination: AnyView
}

To cast 'any view' as an AnyView , simply do this...要将“任何视图”投射为AnyView ,只需执行以下操作...

AnyView(Color.red)

Now, rather than the view being of type Color , it will be of type AnyView .现在,视图不是Color类型,而是AnyView类型。 If you want to use your model, all you would have to do is wrap your desired view in an instance of AnyView when assigning it to the HomePageGridItem.destination variable.如果你想使用你的 model,你所要做的就是在将它分配给HomePageGridItem.destination变量时将你想要的视图包装在AnyView的实例中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM