如何使 SwiftUI 滚动视图缩小到内容?
Posted
技术标签:
【中文标题】如何使 SwiftUI 滚动视图缩小到内容?【英文标题】:How do I make a SwiftUI Scroll view shrink-to-content? 【发布时间】:2021-08-19 04:21:21 【问题描述】:我有一个 SwiftUI GUI,其中有两个堆叠在一起的列表。每个列表都有可变数量的项目。我希望这两个列表都缩小以适应它们的内容。
如果我在 ForEach 周围使用 VStack,那么简单的情况就可以工作(参见下面的示例)。底部附近有一个间隔,因此列表会像我预期的那样移动到窗口的顶部。
现在,有时列表很大,我想要滚动视图和最大高度,但我仍然希望列表在项目较少时缩小。但是一旦我添加了滚动视图,滚动视图就会开始占用它所能占用的所有空间。如果我给它分配一个最大值,那么它就不会再缩小以适应它的内容了。
在下面的示例中(如所写),我得到了我想要的调整大小行为(没有最大大小)。如果我取消注释滚动视图,那么它会占用所有空间,如果我取消注释框架修饰符,它可以工作,但大小是固定的。
struct ContentView: View
@State var List1: [String] = [ ]
@State var List2: [String] = [ ]
var body: some View
VStack
Button("1-5")
List1=[ "1" ]
List2=[ "a", "b", "c", "d", "e" ]
Button("3-3")
List1=[ "1", "2", "3" ]
List2=[ "a", "b", "c" ]
Button("5-1")
List1=[ "1", "2", "3", "4", "5" ]
List2=[ "a" ]
//ScrollView
VStack
ForEach(List1.indices, id: \.self) idx in
Text(List1[idx])
//
//.frame(maxHeight: 40)
Text("middle")
VStack
ForEach(List2.indices, id: \.self) idx in
Text(List2[idx])
Spacer()
Text("last")
【问题讨论】:
这是否回答了您的问题***.com/a/61185571/12299030? 【参考方案1】:您需要PreferenceKey
来计算您的ScrollView
内容的大小。这里有一个getSize
函数可以帮助你:
struct SizePreferenceKey: PreferenceKey
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize)
value = nextValue()
struct SizeModifier: ViewModifier
private var sizeView: some View
GeometryReader geometry in
Color.clear.preference(key: SizePreferenceKey.self, value: geometry.size)
func body(content: Content) -> some View
content.overlay(sizeView)
extension View
func getSize(perform: @escaping (CGSize) -> ()) -> some View
self
.modifier(SizeModifier())
.onPreferenceChange(SizePreferenceKey.self)
perform($0)
您必须比较内容的高度(使用getSize
)和ScrollView
(使用GeometryReader
)的高度,并相应地设置框架:
struct SwiftUIView12: View
@State private var items: [String] = ["One", "Two", "Three"]
@State private var scrollViewSize: CGSize = .zero
var body: some View
GeometryReader proxy in
ScrollView
ForEach(items, id: \.self) item in
Text(item)
.padding()
.frame(maxWidth: .infinity)
.getSize scrollViewSize = $0
.frame(height: scrollViewSize.height < proxy.size.height ? scrollViewSize.height : .none )
.background(Color.blue.opacity(0.2))
.navigationTitle("Test")
.toolbar
Button("Many items")
items = (1 ... 30).map _ in String.random(length: 10)
【讨论】:
以上是关于如何使 SwiftUI 滚动视图缩小到内容?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中查找滚动视图内容是不是已到达内容的末尾
使 ScrollView 中的滚动条在 SwiftUI 中始终可见