简体   繁体   English

使用 GeometryReader 时叠加的 SwiftUI 错误垂直 alignment

[英]SwiftUI erroneous vertical alignment of overlay when using GeometryReader

I have an overlay view that I want to appear hugging the top edge of its parent view (aligned vertically to top not center, see snapshot B) and have the ability to semi-hide it when tapped (move it up so that it doesn't obscure its parent view, and yet have a portion of it visible, say 64 pixels so that it can still be tapped back into original position, see snapshot C).我有一个覆盖视图,我希望它出现在其父视图的顶部边缘(垂直对齐到顶部而不是中心,请参见快照 B),并且能够在点击时半隐藏它(将其向上移动以使其不会t 模糊其父视图,但仍有一部分可见,例如 64 像素,以便仍可以将其轻敲回原始 position,请参见快照 C)。 Problem is that when I use the GeometryReader to get the height of the overlay view I'm trying to move, the overlay appears in the center of the view originally (see snapshot A).问题是当我使用GeometryReader来获取我试图移动的覆盖视图的高度时,覆盖最初出现在视图的中心(参见快照 A)。 And if I don't use the geometry reader I don't know by how much to offset the overlay view:如果我不使用几何阅读器,我不知道要偏移多少覆盖视图:

    @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()
        })
    }

Not sure why geometry reader has this effect on the layout.不知道为什么几何阅读器会对布局产生这种影响。

(A) This is the way it appears with geometry reader code: (A) 这是几何阅读器代码的显示方式:

在此处输入图像描述

(B) If I remove the geometry reader code I get the desired effect: (B)如果我删除几何阅读器代码,我会得到想要的效果:

在此处输入图像描述

(C) And this is the way I want the overlay when moved to the top: (C) 这就是我想要将叠加层移到顶部的方式:

在此处输入图像描述

EDIT: The code displayed above produces the layout (A).编辑:上面显示的代码生成布局 (A)。 I want layout (B) which I get if I omit the geometry reader code.如果我省略几何阅读器代码,我想要布局(B)。

Well... still not sure but here is some approach嗯......仍然不确定,但这里有一些方法

Tested with Xcode 11.4 / iOS 13.4使用 Xcode 11.4 / iOS 13.4 测试

演示

.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()
                    }
            }
    })

You can use the second argument in func overlay<Overlay>(_ overlay: Overlay, alignment: Alignment =.center) to achieve it by aligning it at the top end and moving it up or down with offset depending on the mode.您可以使用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)
            }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM