VStack 不填充 ScrollView 中的屏幕宽度,填充 List

Posted

技术标签:

【中文标题】VStack 不填充 ScrollView 中的屏幕宽度,填充 List【英文标题】:VStack not filling screen width in ScrollView, does fill in List 【发布时间】:2019-06-09 13:54:57 【问题描述】:

我创建了一个可滚动的图像列表,如下所示:

NavigationView 
    List 
        ForEach(landmarks)  landmark in
            landmark.image(forSize: 200)
              // some modifiers...
    
    .navigationBarTitle(Text(category.rawValue))

这是这段代码产生的 UI:

现在,我想去掉 List 创建的行分隔符。因此,我将List 替换为ScrollView。这就是预览显示的内容:

我该如何解决这个问题?

我见过this other similar question,但接受的答案实际上并没有解决问题,而是引入了固定宽度。

【问题讨论】:

你在滚动视图上试过.relativeWidth(<#T##proportion: Length##Length#>)吗?你没有发布你的代码,所以很难判断它是否会起作用。 【参考方案1】:

找到完整的SwiftUI 解决方案。

var body: some View 
    GeometryReader  geometry in
        ScrollView(alwaysBounceVertical: true) 
            VStack 
                // Your code
            .frame(width: geometry.size.width)
        
    .edgesIgnoringSafeArea(.all)


【讨论】:

省略.edgesIgnoringSafeArea(.all) 使其成为一个很好的解决方案。虽然我不确定为什么会这样。这个解决方案看起来也不应该像这样实现。 关键是GeometryReader 避免使用UIKit。 有什么理由避免使用 UIKit? 对 UIKit 的依赖 有没有办法在不使用 UIImage 的情况下加载带有数据的图像? @FlorentMorin【参考方案2】:

我遇到了同样的问题,显然滚动视图使用了尽可能小的尺寸。

您可以将 .frame 修饰符添加到堆栈内的内容中,并将其宽度声明为屏幕的宽度,如下所示:

ContentInsideScrollView  ... .frame(width: UIScreen.main.bounds.width)

注意填充,您的滚动视图可能会超出屏幕的宽度。

否则,您可以将行设置为无限宽:

.frame(minWidth: 0, maxWidth: .infinity)

无论哪种方式,您都必须使用 .frame 修饰符

【讨论】:

该值是可绑定的,还是在旋转设备时会中断? 我真的不知道,很多API还有待发布。你必须做你的测试。但我认为,当您旋转设备时,应该重绘视图,以便您获得新值 没错,我主要是在寻找“未来的读者”。关于检查填充的附加点也是一个很好的。使用屏幕宽度可能会与 iPhone X 上横向模式下的 safeAreaInsets 发生冲突(这可能是也可能不是有意为 scrollView 设计的)。 嗯,这对我来说根本不会影响滚动视图的布局......我必须将 ForEach 包装在 VStack 中,然后将 .frame(width: UIScreen...) 部分应用于该部分,而不是ScrollView 本身。

以上是关于VStack 不填充 ScrollView 中的屏幕宽度,填充 List的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 水平 ScrollView 具有不可见的填充

隐藏 TabBar 时,ScrollView 与 VStack 中的文本重叠

远程图像使用 List 正确加载,但在使用带有嵌入式 VStack 的 ScrollView 和 SwiftUI 时不加载

当嵌入到 SwiftUI 中的 ScrollView 中时,VStack 内的内容会缩小

ScrollView 中的初始 SwiftUI 动画

SwiftUI,ScrollView 在 ZStack 中向上推送 VStack 图像