Компактный размер SwiftUI GeometryReader

Я бы хотел мой LoadingTitle чтобы иметь ширину 70% экрана, поэтому я использую GeometryReader но это увеличивает вертикальный размер, и мой LoadingTitleзанимает гораздо больше вертикального пространства. Хотелось бы, чтобы он оставался максимально компактным.

При использовании жестко запрограммированного width: 300 Получаю правильный макет (кроме относительной ширины):

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            LoadingTitle()
            Color.blue
        }
    }
}

struct LoadingTitle: View {
    var body: some View {
        HStack() {
                Color.gray
            }
            .frame(width: 300, height: 22)
            .padding(.vertical, 20)
            .border(Color.gray, width: 1)
    }
}

Теперь, если я заверну body моего LoadingTitle в GeometryReader Я могу получить правильный относительный размер, но тогда GeometryReader расширяет мой взгляд по вертикали:

struct LoadingTitle: View {

    var body: some View {
        GeometryReader { geo in
            HStack() {
                Color.gray
                    .frame(width: geo.size.width * 0.7, height: 22, alignment: .leading)
                Spacer()
            }
            .padding(.vertical, 20)
            .border(Color.gray, width: 1)
        }
    }
}

Я пробовал использовать .fixedSize(horizontal: false, vertical: true) на GeometryReaderкак и другие предложения, но тогда полученное представление слишком компактно, и все его отступы игнорируются:

Как мне добиться расположения первого скриншота с относительной шириной?

2 ответа

Решение

Вот возможный подход. Протестировано с Xcode 11.4 / iOS 13.4 (без изменений ContentView)

struct LoadingTitle: View {

    var body: some View {
        VStack { Color.clear }
            .frame(height: 22).frame(maxWidth: .infinity)
            .padding(.vertical, 20)
            .overlay(
                GeometryReader { geo in
                    HStack {
                        HStack {
                            Color.gray
                                .frame(width: geo.size.width * 0.7, height: 22)
                        }
                        .padding(.vertical, 20)
                        .border(Color.gray, width: 1)
                        Spacer()
                    }
                }
            )
    }
}

Поскольку у вас есть фиксированная высота заголовка,

      struct LoadingTitle1: View {

    var body: some View {
        GeometryReader { geo in
            HStack {
                HStack {
                    Color.gray
                        .frame(width: geo.size.width * 0.7)
                }
                .padding(.vertical, 20)
                .border(Color.gray, width: 1)
                
                Spacer()
            }
        }.frame(height: 62)
    }
}
Другие вопросы по тегам