Выравнивание LazyHStack в SwiftUI

Вопрос или проблема

Выравнивание LazyHStack в SwiftUI

Есть ли способ выровнять колонки в этом виде по левому краю? Чтобы каждая строка не обязательно имела одинаковое количество колонок?

Вот как это выглядит сейчас:
вставьте описание изображения здесь

И вот код:

struct SizeSelectorView: View {
@State private var selectedSize: String = "medium"

let test = ["small", "medium", "large", "xlarge", "xxlarge"]
let adaptiveColumns = [
    GridItem(.adaptive(minimum: 100))
]
var body: some View {
    ScrollView {
        LazyVGrid(columns: adaptiveColumns, alignment: .leading, spacing: 8) {
            ForEach(test, id: \.self) { size in
                Text(size)
                    .font(.system(size: 14))
                    .foregroundColor(selectedSize == size ? .black : .white)
                    .padding([.top, .bottom], 10)
                    .padding([.leading, .trailing], 16)
                    .background(selectedSize == size ? Color.red : Color.gray2)
                    .cornerRadius(16, corners: .allCorners)
                    .tag(size)
                    .onTapGesture {
                        selectedSize = size
                    }
            }
        }
    }
}

}

Есть ли лучший способ сделать это, кроме LazyVGrid? Я бы хотел, чтобы каждая строка элементов соответствовала/выравнивалась по левому краю и переходила на следующую строку, как только элемент не помещается.

Как

“small” “medium” “large” Spacer()

“xlarge” “xxlarge” Spacer()

Чтобы каждая строка не обязательно имела одинаковое количество колонок?

Хотя вы можете задать количество колонок, занимаемых видом, используя gridCellColumns, я подозреваю, что вы не хотите, чтобы виды занимали фиксированное количество колонок, а вместо этого текли как многострочный текст.

То есть, по определению, это не Grid.

Вам нужно другое расположение, чтобы добиться чего-то подобного. Например, пакет SwiftUI-Flow предлагает такое расположение.

Пример использования:

let test = ["small", "medium", "large", "xlarge", "xxlarge", "foo", "bar", "baz"]
var body: some View {
    ScrollView {
        HFlow {
            ForEach(test, id: \.self) { size in
                Text(size)
                    .font(.system(size: 14))
                    .foregroundColor(selectedSize == size ? .black : .white)
                    .padding([.top, .bottom], 10)
                    .padding([.leading, .trailing], 16)
                    .background(selectedSize == size ? Color.red : Color.gray)
                    .cornerRadius(16)
                    .tag(size)
                    .onTapGesture {
                        selectedSize = size
                    }
            }
        }
    }
}

Результат:

вставьте описание изображения здесь

Вы также можете задать расстояние между элементами, расстояние между строками и т.д.

Ответ или решение

Заголовок: Выравнивание элементов в SwiftUI с использованием LazyHStack и альтернативных решений

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

Ваш текущий код использует LazyVGrid, который по своей сути организует элементы в сетке. Однако, как вы заметили, это может привести к тому, что элементы будут распределены по равномерным колонкам, что не всегда соответствует вашим требованиям.


Решение: Если вы хотите, чтобы элементы выстраивались по левому краю, как текстовые строки, вам следует рассмотреть возможность использования кастомного решения или получение сторонней библиотеки, такой как SwiftUI-Flow. Этот пакет предоставляет возможность выстраивать элементы, как в многострочном тексте, что идеально подходит для ваших целей.

Вот пример использования SwiftUI-Flow:

struct SizeSelectorView: View {
    @State private var selectedSize: String = "medium"

    let test = ["small", "medium", "large", "xlarge", "xxlarge", "foo", "bar", "baz"]

    var body: some View {
        ScrollView {
            HFlow(spacing: 8) {
                ForEach(test, id: \.self) { size in
                    Text(size)
                        .font(.system(size: 14))
                        .foregroundColor(selectedSize == size ? .black : .white)
                        .padding([.top, .bottom], 10)
                        .padding([.leading, .trailing], 16)
                        .background(selectedSize == size ? Color.red : Color.gray)
                        .cornerRadius(16)
                        .tag(size)
                        .onTapGesture {
                            selectedSize = size
                        }
                }
            }
            .padding() // Добавьте отступы при необходимости
        }
    }
}

Объяснение:

  1. HFlow: Используя HFlow от библиотеки SwiftUI-Flow, вы сможете управлять тем, как ваши элементы располагаются в строках. Они будут выстраиваться до тех пор, пока не будет недостаточно места на экране, после чего перейдут на следующую строку.

  2. Свойство spacing: Вы можете установить пространственные отступы между элементами, чтобы они выглядели более аккуратно.

  3. Кастомные отступы: При необходимости вы можете изменить отступы или задать дополнительные стили для каждого элемента.

Этот подход поможет вам достичь желаемого выравнивания элементов по левому краю, создавая визуально приятное представление, где не обязательно будет одно и то же количество колонок в каждой строке.

В заключение, использование LazyVGrid не подходит для ваших целей, и вам стоит обратить внимание на библиотеку SwiftUI-Flow, которая значительно облегчит задачу выравнивания элементов в виде многострочного текста.

Оцените материал
Добавить комментарий

Капча загружается...