Макет в SwiftUI с горизонтальным и вертикальным выравниванием - PullRequest
2 голосов
/ 16 июня 2019

Я пытаюсь выполнить этот макет

desired layout

Если я попробую HStack, завернутый в VStack, я получу это:

HStack in VStack

Если я попробую VStack, завернутый в HStack, я получу это:

VStack in HStack

Есть лиспособ выравнивания базовой линии текста с текстовым полем и получения стандартного интервала от самой длинной метки до начала выровненных текстовых полей?

Ответы [ 2 ]

0 голосов
/ 16 июня 2019
    var body: some View {

    VStack {
        HStack {
            Text("Username")
            Spacer()
            TextField($username)
                .textFieldStyle(.roundedBorder)
                .frame(maxWidth: 200)
                .foregroundColor(.gray)
                .accentColor(.red)
        }
        .padding(.horizontal, 20)
        HStack {
            Text("Email")
            Spacer()
            TextField($email)
                .textFieldStyle(.roundedBorder)
                .frame(maxWidth: 200)
                .foregroundColor(.gray)
            }
            .padding(.horizontal, 20)
        HStack {
            Text("Password")
            Spacer()
            TextField($password)
                .textFieldStyle(.roundedBorder)
                .frame(maxWidth: 200)
                .foregroundColor(.gray)
            }
            .padding(.horizontal, 20)
    }
}

This is the results of the above code. It use an HStack wrapped in a VStack and has the alignment you are trying to achieve

0 голосов
/ 16 июня 2019

Похоже, это будет работать:

extension HorizontalAlignment {
    private enum MyAlignment: AlignmentID {
        static func defaultValue(in context: ViewDimensions) -> Length {
            context[.trailing]
        }
    }
    static let myAlignmentGuide = HorizontalAlignment(MyAlignment.self)
}

struct ContentView : View {
    @State var username: String = ""
    @State var email: String = ""
    @State var password: String = ""

    var body: some View {
        VStack(alignment: .myAlignmentGuide) {
            HStack {
                Text("Username").alignmentGuide(.myAlignmentGuide, computeValue: { d in d[.trailing] })
                TextField($username)
                    .textFieldStyle(.roundedBorder)
                    .frame(maxWidth: 200)
            }
            HStack {
                Text("Email")
                    .alignmentGuide(.myAlignmentGuide, computeValue: { d in d[.trailing] })
                TextField($email)
                    .textFieldStyle(.roundedBorder)
                    .frame(maxWidth: 200)
            }
            HStack {
                Text("Password")
                    .alignmentGuide(.myAlignmentGuide, computeValue: { d in d[.trailing] })
                TextField($password)
                    .textFieldStyle(.roundedBorder)
                    .frame(maxWidth: 200)
            }
        }
    }
}

С помощью этого кода я смогу добиться такой раскладки:

Aligned layout

Предостережение заключается в том, что я должен был указать максимальную ширину для TextField с.Оставленный без ограничений, система макетов, описанная в докладе WWDC, который я связал в комментариях, извлекает размер для TextField до до выравнивания, в результате чего TextField для электронной почты расширяется после конца другогодва.Я не уверен, как решить эту проблему таким образом, чтобы позволить TextField s расширяться до размера содержащего представления, не переходя ...

...