英文:
ScrollView fixed height based content
问题
-
我正在使用
ScrollView
来管理我的View
中文本的显示。 -
当文本非常长时,
ScrollView
应根据文本的大小进行拉伸。我该如何做到这一点? -
我尝试了一些方法,您可以在我的示例中看到。
-
此外,当文本不长时,我需要使
ScrollView
无法滚动。我该如何解决这两个问题?
struct Test2: View {
@State private var contentSize: CGSize = .zero
var body: some View {
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
ScrollView {
Text("这是一个测试文本这是一个测试文本这是一个测试文本这是一个测试")
.padding()
.overlay {
GeometryReader { geo in
Color.clear.onAppear {
contentSize = geo.size
}
}
}
}
}
.background(.white)
.frame(maxHeight: contentSize.height)
}
}
}
请注意,我已经将文本翻译为中文,但代码部分没有进行翻译。
英文:
I'm working with a ScrollView
to manage the display of a text in my View
.
- When the text is very long the
ScrollView
should stretch according to theText
. How can I do this?
I tried a few attempts which you can see here in my example.
- Also I need the
ScrollView
to be non-scrollable when the text is not long. How can I solve these two problems?
struct Test2: View {
@State private var contentSize: CGSize = .zero
var body: some View {
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
ScrollView {
Text ("This is a test textThis is a test texThis is a test texThis is a test")
.padding()
.overlay {
GeometryReader { geo in
Color.clear.onAppear {
contentSize = geo.size
}
}
}
}
}
.background(.white)
.frame(maxHeight: contentSize.height)
}
}
}
答案1
得分: 1
以下是翻译好的内容:
-
The ScrollView已经似乎会在出现时自动调整大小以适应文本,但如果需要在出现后更改文本内容,请尝试在GeometryReader中添加以下内容以在更改时更新大小:
Color.clear.onChange(of: text) { newText in contentSize = geo.size }
不过,你需要一个变量来存储文本内容。
@State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test"
(将
Text("This is...")
替换为Text(text)
) -
这可能不是最高效的方法,但你可以为
scrollDisabled
添加一个变量,以便在文本更改/出现时更新它。在
contentSize
下面添加:@State private var cantScroll: Bool = true
将ZStack嵌套在GeometryReader中(
GeometryReader { viewGeo in...
),然后在每次contentSize
更新时添加代码来检查和比较视图大小:if contentSize.height > viewGeo.size.height { cantScroll = false } else { cantScroll = true }
最后,修改ScrollView:
.scrollDisabled(cantScroll)
最终的代码:
struct Test2: View { @State private var contentSize: CGSize = .zero @State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test" @State private var cantScroll: Bool = true var body: some View { GeometryReader { viewGeo in ZStack { Color.blue .ignoresSafeArea() VStack { ScrollView { Text(text) .padding() .overlay { GeometryReader { geo in Color.clear.onAppear { contentSize = geo.size if contentSize.height > viewGeo.size.height { cantScroll = false } else { cantScroll = true } } Color.clear.onChange(of: text) { _ in contentSize = geo.size if contentSize.height > viewGeo.size.height { cantScroll = false } else { cantScroll = true } } } } } .scrollDisabled(cantScroll) } .background(.white) .frame(maxHeight: contentSize.height) } } } }
希望这对你有所帮助。
英文:
-
The ScrollView already seems to resize to fit the text when it appears, but if you need to change the text content after it appears, try adding this in the GeometryReader to update the size when it changes:
Color.clear.onChange(of: text) { newText in contentSize = geo.size }
You would need a variable for the text though.
@State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test"
(replace Text("This is...")
with Text(text)
)
- It's probably not the most efficient way, but you can have a variable for
scrollDisabled
that updates when the text changes/appears.
Underneath contentSize
:
@State private var cantScroll: Bool = true
Embed ZStack in GeometryReader (GeometryReader { viewGeo in...
), then
add code to check and compare view sizes whenever contentSize
updates:
if contentSize.height > viewGeo.size.height {
cantScroll = false
} else {
cantScroll = true
}
And finally, modify ScrollView:
.scrollDisabled(cantScroll)
Final code:
struct Test2: View {
@State private var contentSize: CGSize = .zero
@State private var text: String = "This is a test textThis is a test texThis is a test texThis is a test"
@State private var cantScroll: Bool = true
var body: some View {
GeometryReader { viewGeo in
ZStack {
Color.blue
.ignoresSafeArea()
VStack {
ScrollView {
Text(text)
.padding()
.overlay {
GeometryReader { geo in
Color.clear.onAppear {
contentSize = geo.size
if contentSize.height > viewGeo.size.height {
cantScroll = false
} else {
cantScroll = true
}
}
Color.clear.onChange(of: text) {
_ in
contentSize = geo.size
if contentSize.height > viewGeo.size.height {
cantScroll = false
} else {
cantScroll = true
}
}
}
}
}
.scrollDisabled(cantScroll)
}
.background(.white)
.frame(maxHeight: contentSize.height)
}
}
}
}
I hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论