SwiftUI: Как должны быть сформулированы представления ForEach, чтобы превратить строки из массива в представления Text ()? - PullRequest
0 голосов
/ 25 марта 2020

Я несколько безуспешно пытался выяснить, как работать с представлением SwiftUI ForEach. С помощью следующих ресурсов, таких как this , this и this , мне кажется, что данный массив строк:

var arrayOfStrings: [String] = ["String1", "String2", "String3"]

... каждая из следующих реализаций должна работать:

ForEach(arrayOfStrings, id: \.self) {
    Text(arrayOfStrings[$0])
}

ForEach(1...arrayOfStrings.count, id: \.self) {
    Text(arrayOfStrings[$0])
}

ForEach(arrayOfStrings, id: \.self) { string in
    Text(string)
}

И все же каждая из них выдает мне ошибку во время компиляции или вылетает из приложения во время выполнения.

Выше приведен пример кода, но если вам нужен полный контекст того, что я пытаюсь сделать, вот он:

struct Infobox<Content>: View where Content: View {
    let edgeSize: CGFloat = 8
    let color: Color = .neoblå
    let content: Content

    var body: some View {
        VStack(spacing: 0) {
            BoxSide(.top, withColor: color)
                .frame(height: edgeSize)
                .padding(.horizontal, 0)

            content
                .background(color)

            BoxSide(.bottom, withColor: color)
                .frame(height: edgeSize)
                .padding(.horizontal, 0)
        }
    }

    init(@ViewBuilder _ content: @escaping () -> Content) {
        self.content = content()
    }

    init<T: View>(withHeader headerText: String, forContentArray contentArray: [(text: String, value: String)], splitInTwoColumns twoColumns: Bool, @ViewBuilder ignoreTheClosure: @escaping () -> T) where Content == VStack<TupleView<(HStack<TupleView<(Spacer, Text, Spacer)>>, HStack<TupleView<(VStack<ForEach<ClosedRange<Int>, Int, Text>>, VStack<ForEach<ClosedRange<Int>, Int, Text>>, Spacer, VStack<ForEach<ClosedRange<Int>, Int, Text>>, VStack<ForEach<ClosedRange<Int>, Int, Text>>)>>)>> {

        var column1: [String] = []
        var column2: [String] = []
        var column3: [String] = []
        var column4: [String] = []

        let halfArray = contentArray.count/2
        for (index, content) in contentArray.enumerated() {
            if index+1 <= halfArray {
                column1.append(content.text)
                column2.append(content.value)
            } else {
                column3.append(content.text)
                column4.append(content.value)
            }
        }

        self.init() {

            VStack(alignment: .leading) {
                HStack() {
                    Spacer()
                    Text(headerText)
                        .font(.headline)
                    Spacer()
                }
                HStack {
                    VStack {
                        ForEach(column1, id: \.self) {
                            Text(column1[$0])
                        }
                    }
                    VStack {
                        ForEach(column2, id: \.self) {
                            Text(column2[$0])
                        }
                    }
                    Spacer()
                    VStack {
                        ForEach(column3, id: \.self) {
                            Text(column3[$0])
                        }
                    }
                    VStack {
                        ForEach(column4, id: \.self) {
                            Text(column4[$0])
                        }
                    }
                }
            }
        }
    }
}

Резюме: С учетом массива (String, String ), создайте Infobox (), состоящий из элементов Text (), разделенных на четыре столбца (два для «ключей» и два для соответствующих значений).

Если у кого-либо есть идеи, как исправить эти представления ForEach, Я дам тебе повара ie:)

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Просто быстрый вопрос, почему вы используете ForEach вместо списка? Просто любопытно.

0 голосов
/ 25 марта 2020

Это ошибка, потому что $0 - это String, и вы не можете индексировать строковый массив строкой

ForEach(arrayOfStrings, id: \.self) {
    Text(arrayOfStrings[$0])
}

Эта ошибка не выполняется, потому что индексы массива основаны на 0 -> Выберите 0 базовый диапазон: 0..<arrayOfStrings.count, чтобы избежать «исключения индекса за пределами»

ForEach(1...arrayOfStrings.count, id: \.self) {
    Text(arrayOfStrings[$0])
}

Это правило, как правило, правильное, но вам, возможно, придется ссылаться на свой элемент, квалифицированный в области действия self.arrayOfStrings, это применимо на весь код SwiftUI, когда ваша область видимости является замыканием:

ForEach(arrayOfStrings, id: \.self) { string in
    Text(string)
}

Это более быстрый способ доступа к массиву через индекс:

ForEach(arrayOfStrings.indices) {
  Text(self.arrayOfStrings[$0])
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...