【问题标题】:Views compressed by other views in SwiftUI VStack and ListSwiftUI VStack 和 List 中其他视图压缩的视图
【发布时间】:2019-06-08 14:59:23
【问题描述】:

在我的 SwiftUI 应用程序中,我正在尝试实现类似这样的 UI:

我已经为类别 1 和类别 2 添加了两行。结果如下所示:

NavigationView {
    VStack(alignment: .leading) {
        CategoryRow(...)
        CategoryRow(...)
        Spacer()
    }
    .navigationBarTitle(Text("Featured"))
}

现在,当添加第三个类别的视图(带有图像的 VStack)时,会发生以下情况:

这发生在我将Spacer()替换为VStack之后:

VStack(alignment: .leading) {
    Text("Rivers")
        .font(.headline)
    ForEach(self.categories["Rivers"]!.identified(by: \.self)) { landmark in
        landmark.image(forSize: 200)
    }
}

我的CategoryRow实现如下:

VStack(alignment: .leading) {
    Text(title)
        .font(.headline)
    ScrollView {
        HStack {
            ForEach(landmarks) { landmark in
                CategoryItem(landmark: landmark, isRounded: self.isRounded)
            }
        }
    }
}

问题

似乎视图被压缩了。我找不到任何抗压缩性或包含优先级修饰符的内容来解决此问题。
我还尝试在CategoryRow 上使用.fixedSize() 和.frame(width:height:)。

如何防止压缩这些视图?


更新

我尝试将整个外部堆栈视图嵌入到滚动视图中:

NavigationView {
    ScrollView { // also tried List
        VStack(alignment: .leading) {
            CategoryRow(...)
            CategoryRow(...)
            ForEach(...) { landmark in
                landmark.image(forSize: 200)
            }
        }
        .navigationBarTitle(Text("Featured"))
    }
}

...结果更糟:

【问题讨论】:

  • 你试过.scaledToFit()吗?

标签: swift swiftui


【解决方案1】:

你可能会阻止 VStack 中的视图被压缩使用

  .fixedSize(horizontal: false, vertical: true)

例如: 我有以下 VStack:

VStack(alignment: .leading){
        ForEach(group.items) {
            FeedCell(item: $0)
        }
    }

哪个渲染压缩的Text()

当我添加 .fixedSize(horizo​​ntal: false, vertical: true) 它不再压缩了

VStack(alignment: .leading){
        ForEach(group.items) {
            FeedCell(item: $0)
                .fixedSize(horizontal: false, vertical: true)
        }
    }

【讨论】:

  • 谢谢。我有多行 Text() 和 Image().resizable() 争取垂直空间,这样我就能够强制文本优先并抵抗压缩。
【解决方案2】:

您可以尝试将layoutPriority() 运算符添加到您的第一个VStack。这是文档中关于该方法的内容:

在一组同级视图中,提高视图的布局优先级会鼓励该视图在组收缩时稍后收缩,并在组拉伸时更快地拉伸。

所以它有点像 Autolayout 中的内容压缩阻力优先级。但是这里的默认值是0,所以你只要把它设置为1就可以得到想要的效果,像这样:

VStack(alignment: .leading) {
    CategoryRow(...)
    CategoryRow(...)
    Spacer()
}.layoutPriority(1)
VStack(alignment: .leading) {
    ...
}

希望它有效!

【讨论】:

    【解决方案3】:

    似乎没有足够的空间容纳您在 VStack 中的所有视图,它会压缩其中的一些视图。您可以将其嵌入到ScrollView

    NavigationView {
     ScrollView {
       VStack(alignment: .leading) {
          CategoryRow(...)
          CategoryRow(...)
          /// you images and so on
       }
      }
    }
    

    【讨论】:

    • 好吧,我就是这么做的,但同样的事情发生了:视图被压缩了,都使用了 ScrollView 和 List。
    【解决方案4】:
    struct ContentView1: View {
        var body: some View {
            NavigationView {
                ScrollView {
                    VStack {
                        CategoryListView {
                            CategoryView()
                        }
    
                        CategoryListView {
                            SquareCategoryView()
                        }
                        
                        CategoryListView {
                            RectangleCategoryView()
                        }
                    }
                    .padding()
                }
                .navigationTitle("Featured")
            }
        }
    }
    
    struct CategoryListView<Content>: View where Content: View {
        private let viewSize: CGFloat = 150
        var content: () -> Content
        
        init(@ViewBuilder content: @escaping () -> Content) {
            self.content = content
        }
        
        var body: some View {
            VStack {
                HStack {
                    Text("Category name")
                    Spacer()
                }
                ScrollView(.horizontal, showsIndicators: false){
                    HStack {
                        ForEach(0..<10) { _ in
                            content()
                        }
                    }
                }
            }
        }
    }
    
    struct ContentView1_Previews: PreviewProvider {
        static var previews: some View {
            ContentView1()
        }
    }
    
    struct CategoryView: View {
        private let viewSize: CGFloat = 150
        var body: some View {
            Circle()
                .fill()
                .foregroundColor(.blue)
                .frame(width: viewSize, height: viewSize)
        }
    }
    
    struct RectangleCategoryView: View {
        private let viewSize: CGFloat = 350
        var body: some View {
            Rectangle()
                .fill()
                .foregroundColor(.blue)
                .frame(width: viewSize, height: viewSize * 9 / 16)
        }
    }
    
    struct SquareCategoryView: View {
        private let viewSize: CGFloat = 150
        var body: some View {
            Rectangle()
                .fill()
                .foregroundColor(.blue)
                .frame(width: viewSize, height: viewSize)
        }
    }
    

    【讨论】:

      【解决方案5】:

      我认为您的最顶层视图(在 NavigationView 中)需要是一个列表,以便它可以滚动:

      NavigationView {
                  List {
                      ...
      

      或者使用 ScrollView。

      堆栈自动适应屏幕。如果您希望您的内容超出此范围,您将使用 ScrollView 或 TableView 等 i UIKit

      编辑:

      实际上,谷歌搜索带来了这个结果,这似乎正是您正在制作的: https://developer.apple.com/tutorials/swiftui/composing-complex-interfaces

      【讨论】:

      • 好吧,我确实做到了,但同样的事情发生了:视图被压缩,都使用 ScrollView 和 List。是的,我有那个教程的屏幕截图,但即使他们在那里显示,他们并没有完全实现那个 UI,而是 3 个类别行。由于每一个都不是很高,它们不会到达视图的底部,因此,首先不要被压缩。
      • 查看我编辑的问题。我还尝试完全删除最顶层的堆栈视图,以便 CategoryRows 直接在 List/ScrollView 内 - 不走运。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      相关资源
      最近更新 更多