在ForEach视图中使用条件条件将不同的效果应用于每个视图

时间:2020-05-18 20:39:51

标签: swiftui

我正在尝试呈现数组中的项目列表。数组项是具有字符串和整数的结构。我希望将整数大于0的数组的项目向左对齐,等于0的居中对齐,而小于0则向右对齐。将来,我希望能够应用一些其他差异,但现在我只需要不同的对齐方式即可。

我尝试使用ForEach视图循环遍历数组中的项目,并使用if else语句尝试两种不同的显示方式,但我遇到一个错误,使()无法适应“视图”。

编辑:添加确切的错误消息:Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols

这是我在ForEach中循环的结构:

struct PreviouslyPlayedData: Hashable {
        let text: String
        let speaker: Int
    }

这是我现在设置的ForEach,它给出了错误。

ForEach(previouslyPlayed, id: \.self) { data in
                if (data.speaker == 0) {
                    Text(data.text)
                    .frame(width: 300, height: nil, alignment: .center)
                } else {
                    Text(data.text)
                        .frame(width: 300, height: nil, alignment: .leading)
                }

            }

2 个答案:

答案 0 :(得分:4)

您不能在- >中使用条件条件。

SwiftUI在幕后做了很多工作,它只是希望--中仅包含一种非常特定的View类型。它不在乎WHICH类型的视图(因此ForEach),但是它在乎只能返回一种类型的视图。尽管有时您可以保证在条件条件下,但是Swift不能完全为您解决问题。

您可以通过多种方法来解决此问题。如果您的逻辑相对简单并且不需要太多修改,则可以使用三元运算符来切换样式:

ContentView

答案 1 :(得分:1)

另一种方法是在其自己的视图中显示每个项目,该视图可以根据项目处理对齐方式,并使用主内容视图显示列表:

例如:

import SwiftUI

struct PreviouslyPlayedData: Identifiable {
    let id = UUID() // To make it easier to use in lists
    let text: String
    let speaker: Int

    static var previewItems: [PreviouslyPlayedData] {
        [PreviouslyPlayedData(text: "First", speaker: -1),
         PreviouslyPlayedData(text: "Second", speaker: -1),
         PreviouslyPlayedData(text: "third", speaker: 0),
         PreviouslyPlayedData(text: "Fourth", speaker: 1),
         PreviouslyPlayedData(text: "Fifth", speaker: -1),
         PreviouslyPlayedData(text: "Sixth", speaker: 2),
        ]
    }
}

struct ContentView: View {
    var items = PreviouslyPlayedData.previewItems

    var body: some View {
        List(items) { item in
            DataView(item: item)
        }
    }
}

struct DataView: View {
    let item: PreviouslyPlayedData

    var itemAlignment: Alignment {
        if item.speaker < 0 {
            return .leading
        } else if item.speaker == 0 {
            return .center
        } else {
            return .trailing
        }
    }


    var body: some View {
        Text(item.text).frame(maxWidth: .infinity, alignment: itemAlignment)
    }
}

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

外观如下:

enter image description here