Как создать сетку из 2 столбцов с квадратными ячейками в SwiftUI

Я пытаюсь воспроизвести этот пользовательский интерфейс в SwiftUI с помощью сетки.

Я создал такую ​​ячейку.

      struct MenuButton: View {
    let title: String
    let icon: Image
    
    var body: some View {
        Button(action: {
            print(#function)
        }) {
            VStack {
                icon
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 60, height: 60)
                Text(title)
                    .foregroundColor(.black)
                    .font(.system(size: 20, weight: .bold))
                    .multilineTextAlignment(.center)
                    .padding(.top, 10)
            }
        }
        .frame(width: 160, height: 160)
        .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.fr_primary, lineWidth: 0.6))
    }
}

И Грид вроде так.

      struct LoginUserTypeView: View {
    private let columns = [
        GridItem(.flexible(), spacing: 20),
        GridItem(.flexible(), spacing: 20)
    ]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns, spacing: 30) {
                ForEach(Menu.UserType.allCases, id: \.self) { item in
                    MenuButton(title: item.description, icon: Image(item.icon))
                }
            }
            
            .padding(.horizontal)
            .padding()
        }
    }
}

Но на экранах меньшего размера, таких как iPod, ячейки перекрываются.

На больших экранах iPhone расстояние все равно неправильное.

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

1 ответ

MenuButton имеет фиксированную ширину и высоту, поэтому ведет себя некорректно.


Вы могли бы использовать .aspectRatio и .frame(maxWidth: .infinity, maxHeight: .infinity) за это:

      struct MenuButton: View {
    let title: String
    let icon: Image

    var body: some View {
        Button(action: {
            print(#function)
        }) {
            VStack(spacing: 10) {
                icon
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(maxWidth: 60, maxHeight: 60)
                Text(title)
                    .foregroundColor(.black)
                    .font(.system(size: 20, weight: .bold))
                    .multilineTextAlignment(.center)
            }
            .padding()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .aspectRatio(1, contentMode: .fill)
        .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color. fr_primary, lineWidth: 0.6))
    }
}
Другие вопросы по тегам