SwiftUI неверное вертикальное выравнивание наложения при использовании GeometryReader - PullRequest
1 голос
/ 26 апреля 2020

У меня есть накладываемое представление, которое я хочу обнять верхним краем своего родительского вида (выровненное по вертикали сверху, а не по центру, см. Снимок B) и имею возможность скрыть его при касании (переместить его вверх, чтобы он не затеняет свой родительский вид, но при этом имеет видимую часть, скажем, 64 пикселя, чтобы его можно было снова вернуть в исходное положение, см. снимок C). Проблема в том, что когда я использую GeometryReader, чтобы получить высоту наложения, которое я пытаюсь переместить, наложение первоначально появляется в центре вида (см. Снимок A). И если я не использую считыватель геометрии, я не знаю, насколько смещен вид наложения:

    @State var moveOverlay = false

    var body : some View {

        VStack {
            ForEach(0...18, id: \.self) { _ in
                Text("This is the background... This is the background... This is the background... This is the background... ")
            }
        }
        .overlay(VStack {
            GeometryReader { proxy in
                Text("This is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\n")
                    .lineLimit(9)
                    .background(Color.gray)
                    .padding(32)
                    .frame(maxWidth: nil)
                    .offset(x: 0, y: self.moveOverlay ? -proxy.size.height + 128 + 64 : 0)
                    .onTapGesture {
                        self.moveOverlay = !self.moveOverlay
                }
            }
            Spacer()
        })
    }

Не уверен, почему считыватель геометрии оказывает такой эффект на макет.

(A) Вот как это выглядит с кодом считывателя геометрии:

enter image description here

(B) Если я удаляю код считывателя геометрии, я получаю желаемое Эффект:

enter image description here

(C) И вот как я хочу, чтобы наложение было перемещено наверх:

enter image description here

РЕДАКТИРОВАТЬ: код, показанный выше создает макет (A). Я хочу макет (B), который я получу, если опущу код считывателя геометрии.

Ответы [ 2 ]

2 голосов
/ 26 апреля 2020

Ну ... все еще не уверен, но вот какой-то подход

Протестировано с Xcode 11.4 / iOS 13.4

demo

.overlay(
    ZStack(alignment: .top) {
        Color.clear
        Text("This is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\n")
                .lineLimit(9)
                .background(Color.gray)
                .alignmentGuide(.top) { self.hideOverlay ? $0.height * 3/2 : $0[.top] - 64 }
                .onTapGesture {
                    withAnimation(Animation.spring()) {
                        self.hideOverlay.toggle()
                    }
            }
    })
1 голос
/ 26 апреля 2020

Вы можете использовать второй аргумент в func overlay<Overlay>(_ overlay: Overlay, alignment: Alignment = .center) для его достижения, выровняв его по верхнему краю и переместив его вверх или вниз со смещением в зависимости от режима.

struct AlignmentView: View {
    @State var hideOverlay = false

    var body : some View {
        GeometryReader{ proxy in
            VStack {
                ForEach(0...18, id: \.self) { _ in
                    Text("This is the background... This is the background... This is the background... This is the background... ")
                }
            }
            .overlay(
                Text("This is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\nThis is the overlay text snippet sentence that is multiline...\n")
                        .lineLimit(9)
                        .background(Color.gray)
                        .frame(maxWidth: nil)
                        .offset(x: 0, y: self.hideOverlay ? -proxy.size.height / 5.0 : 50)
                        .onTapGesture {
                            withAnimation {
                                self.hideOverlay.toggle()
                            }
            },
                alignment: .top)
            }
    }
}
...