ScrollView 内的 GeometryReader 折叠 GeometryReader,无论子级大小如何 [英] GeometryReader inside a ScrollView collapses the GeometryReader, regardless of child sizes

查看:33
本文介绍了ScrollView 内的 GeometryReader 折叠 GeometryReader,无论子级大小如何的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个包含绘图的子视图,我希望该绘图的大小与父容器的一小部分成比例.

这很好用,除非放在层次结构中某个位置的滚动视图中.

从截图中可以看出,当堆栈内部的声音达到预期的最大时.但是,当您放入滚动视图时,几何阅读器的大小会折叠到接近于零,并且其子项会溢出其边界.就好像它在不同的 Z 索引上呈现它的孩子一样.事实上,如果您从几何渲染内容中移除包装 VStack,它实际上不会像包装在 ZStack 中一样布局其所有子项.

需要明确的是:ScrollView 归组件所有.组件不应该知道它是否在 ScrollView 中 - 它只是一个可怜的无助组件,被扔掉了.这就是为什么我将 ScrollView 放入预览代码中,而不是组件中.

我尝试了各种固定尺寸、男士、杂志和理想的组合.我能找到的唯一解决方法是这个

ScrollView(看看几何图形的红框是如何折叠到大小 10 的):

还要注意,无论有没有圆圈都会出现同样的问题,这也是我遇到的问题.所以就宽度捕获而言,它不是鸡/蛋,至少在圈子方面.我希望 Text 组件知道它们自己的大小,并且会告诉 GR.

对比

解决方案

这是一种粗糙的(无子视图分离)可能的布局解决方案.如果/当内部子视图分开时,几何宽度可以通过构造函数参数注入.

使用 Xcode 12 测试.

struct TestScrollViewWithGeometry: View {var主体:一些视图{GeometryReader{ g in滚动视图{虚拟堆栈{让宽度 = g.size.widthCircle().frame(width:width/3,height:width/3,alignment:.center)文本(内部地理")文本(内部地理")文本(内部地理\(宽度)")文本(内部地理")文本(内部地理")}.border(颜色.绿色,宽度:2)文本(下一个滚动视图项")}.border(颜色.蓝色,宽度:2)}.border(颜色.红色,宽度:3)}}

I'm trying to make a sub view which contains a drawing which I want the size to be proportional to a fraction of the parent container.

This works fine except when put inside a scroll view somewhere up the hierarchy.

As seen from the screenshots when inside of the stack the loudest as expected. But when you put inside a scroll view the size of the geometry reader collapses to near zero and its children overflow its boundaries. As though it's rendering its children on a different Z index. In fact if you remove the wrapping VStack from the geometry render contents it doesn't fact layout all its children as though it were wrapped in a ZStack.

EDIT: To be clear: the ScrollView is not owned by the component. The component should not be aware if it's in a ScrollView or not - it's just a poor helpless component, being thrown around. That's why I put the ScrollView into the preview code, not the component.

I've tried all sorts of combinations of fixed sizes and men and mags and ideal. The only work around I could find was this hacky solution - the edited part of the question near the bottom where the width reported by the geometry reader is captured through a workaround into a state variable and then re-used to set the frame size of a sibling view.

Note, I'm a complete beginner. There seems to be some interaction between the scroll view and the geometry reader that is beyond my current understanding.

Seems to be a confusing topic.

import SwiftUI

struct ScrollViewGeoReader: View {
    var body: some View {
        GeometryReader{ g in
            VStack{
                let width = g.size.width
                Circle().frame(width: width/3, height: width/3, alignment: .center)
                Text("inside geo")
                Text("inside geo")
                Text("inside geo \(width)")
                Text("inside geo")
                Text("inside geo")
            }
            .border(Color.green, width: 2)
        }
        .border(Color.red, width: 3)
    }
}

struct ScrollViewGeoReader_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
//            VStack {
            ScrollView {
                ScrollViewGeoReader()
                Text("Next scrollview item")
            }
            .border(Color.blue, width: 2)

        }
    }
}

ZStack (expected layout):

ScrollView (see how the red frame of the geometry read it has collapsed to size 10):

EDIT:

Also note that the same problem occurs with or without the circle, which is also a problem I have. So it's not chicken / egg as far as the width capturing is concerned, at least in terms of Circles. I would have though the Text components know their own size, and would tell the GR.

vs

解决方案

Here is scratchy (w/o subviews separation) possible solution for layout. If/when internal subviews separated the geometry width can be injected by constructor arguments.

Tested with Xcode 12.

struct TestScrollViewWithGeometry: View {
    var body: some View {
        GeometryReader{ g in
            ScrollView {
                VStack{
                    let width = g.size.width
                    Circle().frame(width: width/3, height: width/3, alignment: .center)
                    Text("inside geo")
                    Text("inside geo")
                    Text("inside geo \(width)")
                    Text("inside geo")
                    Text("inside geo")
                }
                .border(Color.green, width: 2)
                Text("Next scrollview item")
            }
            .border(Color.blue, width: 2)
        }
        .border(Color.red, width: 3)
    }
}

这篇关于ScrollView 内的 GeometryReader 折叠 GeometryReader,无论子级大小如何的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆