【问题标题】:How to use geometry reader so that the view does not expand?如何使用几何阅读器使视图不扩展?
【发布时间】:2020-11-10 23:36:37
【问题描述】:

我用过这样的几何阅读器

GeometryReader { r in
   ScrollView {
      Text("SomeText").frame(width: r.size.width / 2)
   }
}

问题在于阅读器垂直扩展很像Spacer()。 无论如何,我可以让它这样做吗?

【问题讨论】:

  • 你想让 Text 视图是 ScrollView 的一半宽度?
  • 不,这只是一个例子。我需要的是问题中提到的内容。我想使用几何阅读器,但我不希望几何阅读器的不良副作用是 --> 它会在水平和垂直方向上扩展整个视图。
  • 如果您希望文本视图为内容大小的一半,则无法完成,因为文本也在内容本身内。 :)
  • 我不希望文本视图是内容大小的一半。

标签: swiftui


【解决方案1】:

谷歌搜索后,我找到了这个答案here

创建这个新结构

struct SingleAxisGeometryReader<Content: View>: View {
    private struct SizeKey: PreferenceKey {
        static var defaultValue: CGFloat { 10 }
        static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
            value = max(value, nextValue())
        }
    }

    @State private var size: CGFloat = SizeKey.defaultValue
    var axis: Axis = .horizontal
    var alignment: Alignment = .center
    let content: (CGFloat)->Content

    var body: some View {
        content(size)
            .frame(maxWidth:  axis == .horizontal ? .infinity : nil,
                   maxHeight: axis == .vertical   ? .infinity : nil,
                   alignment: alignment)
            .background(GeometryReader {
                proxy in
                Color.clear.preference(key: SizeKey.self, value: axis == .horizontal ? proxy.size.width : proxy.size.height)
            }).onPreferenceChange(SizeKey.self) { size = $0 }
    }
}

然后像这样使用它

SingleAxisGeometryReader { width in  // For horizontal
   // stuff here
}

SingleAxisGeometryReader(axis: .vertical) { height in  // For vertical
   // stuff here
}

有了这个答案,它现在是通用的,无需更改代码。

【讨论】:

  • 这太有用了,简直不敢相信它不是几何阅读器的默认设置。
  • 是的,我认为 SwiftUI 的边缘还是有点粗糙
  • 这个视图可能会在过渡动画中弄乱,小心
  • @crow 我没有尝试过动画,也许有人可以改进响应以进行修复
【解决方案2】:

因为背景总是适合实际视图大小。你可以使用这个技巧,在后台添加 GeometryReader 而不会改变视图本身的大小。

       ScrollView {
        
    }.background(
        GeometryReader { r in
            // stuff
        }
    )
}

【讨论】:

  • 这正确地不会让它扩展,但我需要 r 在 ScrollView 中可用,以便滚动视图的内容可以根据 r 调整大小
  • 如果需要取滚动视图的内容大小?那么我们可以使用另一种正确的方法。所以请更改问题,然后我将编辑我的答案。
  • 我已经编辑了问题,并在滚动视图中添加了Text() 对象。
  • 我想在另一个地方使用大小作为@state,谢谢!
【解决方案3】:

如果它实际上不是您在顶部提供的代码,那么您实际上试图对视图做什么有点不清楚。不过,关于这一点,您可以交换 GeometryReader 和 ScrollView 的位置。 GeometryReader 所做的是找到可用空间的框架,并填充它。使用 ScrollView,实际高度为 0。所以,这个:

ScrollView {
       GeometryReader {r in
          Text("SomeText").frame(width: r.size.width / 2)
       }
    }

【讨论】:

  • 把它放在 ScrollView 的末尾。 .border(Color.black, width: 1) 你会看到 ScrollView(因为几何阅读器)占据了屏幕的整个宽度和高度。我正试图让这发生。
  • 为什么?您是否正在尝试解决一些实际的具体问题?或者您只是假设性地试图让 GeometryReader 以它不具备的方式运行?关于我上面的回答,占据整个屏幕高度的 ScrollView 实际上与 GeometryReader 无关:
  • ScrollView { Text("SomeText").frame(maxWidth: .infinity) }.border(Color.black, width: 1)
  • 也许不是高度(在这种特殊情况下)。但是你可以看到它确实占据了整个宽度,对吧?在其他情况下,它确实占据了整个高度。我想重点是这个。我想使用 GeometryReader,但没有 GeometryReader 打乱我的观点。我目前有一个更复杂的视图,GeometryReader 的这种副作用使我的视图扩展到最大容量。我不希望它以这种方式表现,因为它弄乱了我的布局。如果我需要更清楚,请告诉我。
  • 你需要比这更清楚。您需要发布实际代码。它不必是精确的,但它需要对所涉及的所有视图进行某种表示。否则,您最初问题的答案是明确的“否”。没有办法做到这一点。然而,几乎可以肯定有一种方法可以让您的视图正确布局,而且根本不需要使用 GeometryReader。因此,发布一个更详细的示例。然后,有人可能会解决您的问题。
猜你喜欢
  • 2015-07-10
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-04-04
相关资源
最近更新 更多