SwiftUI - 如何根据列表为文本设置不同的值

Posted

技术标签:

【中文标题】SwiftUI - 如何根据列表为文本设置不同的值【英文标题】:SwiftUI - How to have different value for Text according to a List 【发布时间】:2020-02-26 20:28:12 【问题描述】:
import SwiftUI

struct ContentView: View 

  let disciplines = ["Potato", "Tomato", "Onion"]

  var body: some View 
        NavigationView
            List(disciplines, id: \.self)  discipline in
                NavigationLink(
                    destination: DetailView(discipline: discipline)) 
                        Text(discipline)
                    
            
            .navigationBarTitle (Text("The App Title"), displayMode: .inline)
        
    




struct DetailView: View 
  let discipline: String
  var body: some View 
    Text(discipline)
  



struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

例如,现在,当我在列表中点击“土豆”时,视图中的文本将显示“土豆”。 但我希望列出的每个文本都有不同的文本,而不是同一个词。

如何使用 SwiftUI 做到这一点?

谢谢。

【问题讨论】:

【参考方案1】:

您可以创建一个ingredient 对象并拥有两个字段。一个用于name,一个用于description

struct Ingredient: Identifiable 
    var id = UUID()
    var name: String
    var description: String

这样,您必须将您的 disciplines 修改为以下内容以获取 ingredient 对象而不是字符串

    let disciplines = [Ingredient(name: "Potato", description: "Yummy potato"),
                       Ingredient(name: "Tomato", description: "Yummy Tomato"),
                       Ingredient(name: "Onion", description: "Yummy Onion")]

并且您的视图会稍微改变以使用 ingredient 对象中的 namedescription 字段

    var body: some View 
        NavigationView
            List(disciplines)  discipline in
                NavigationLink(
                destination: DetailView(discipline: discipline.description)) 
                    Text(discipline.name)
                
            
            .navigationBarTitle (Text("The App Title"), displayMode: .inline)
        
    

【讨论】:

完美!谢谢。 如何添加默认值,现在当应用程序开始运行时,详细视图中没有任何内容,如何设置应用程序启动时的内容? @sfung3 你能再解释一下吗?由于NavigationLink @newGuy12,除非disciplines 中有元素,否则您无法访问DetailView 我的意思是代码运行良好,但是当您打开应用程序时,描述侧没有任何内容,它是空的,直到您从边表中点击某些内容并获取您的描述轻拍。所以我的问题是,如何让它在打开应用程序时在描述中有一些东西?(即使用户仍然没有点击任何东西)。 @sfung3 谢谢! 这适用于 iPadOS 吗?【参考方案2】:

在下面的示例中,我使用了MVVM 概念来分隔视图及其逻辑。接下来,ViewModel 包含两个数组/字典:

1 . disciplinesIds 拥有唯一的 ID 来识别学科 2. disciplines 保存要显示的项目,映射到 id

import SwiftUI

struct discipline 
    let name: String
    let content: String


final class ContentViewModel: ObservableObject 
    @Published var disciplinesIds: [UUID] = []
    @Published var disciplines: [UUID : discipline] = [:]

    init() 
        for item: String in ["Potato", "Tomato", "Onion"] 
            let id = UUID()

            self.disciplinesIds.append(id)
            self.disciplines[id] = discipline(name: item, content: item + "_content")
        
    



struct ContentView: View 
    @ObservedObject var viewModel: ContentViewModel

    var body: some View 
        NavigationView
            List(self.viewModel.disciplinesIds, id: \.self)  discipline in
                NavigationLink(destination: DetailView(discipline: self.viewModel.disciplines[discipline]!.content)) 
                    Text(self.viewModel.disciplines[discipline]!.name)
                
            
            .navigationBarTitle (Text("The App Title"), displayMode: .inline)
        
    


struct DetailView: View 
    let discipline: String

    var body: some View 
        Text(discipline)
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView(viewModel: .init())
    

在您的视图中,为了提高性能,遍历 id 列表(请参阅article),而不是使用字典本身。您甚至可以将discipline 对象传递给视图DetailView

【讨论】:

以上是关于SwiftUI - 如何根据列表为文本设置不同的值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中使用 .refreshable 调用 API 并刷新列表

如何在 SwiftUI 中动画/过渡文本值更改

如何根据 SwiftUI 中的日期将事件分成列表的不同部分?

如何在 SwiftUI 中对列表中的值求和?

根据元素是否包含文本,为元素设置不同的值

每个部分具有不同单元格的 SwiftUI 列表