我有一个
.sheet
,当按下按钮时启动,它显示一个 DisclosureGroup
,其中有 List
项目,在最底部有一个 DisclosureGroup
,其中有一些文本和 Button
:
struct TestView: View
{
@State private var sheetIsPresented: Bool = false
@State private var outerDisclosureIsExpanded: Bool = false
@State private var innerDisclosureIsExpanded: Bool = false
var body: some View
{
Button
{
self.sheetIsPresented = true
}
label:
{
Label("Add Item", systemImage: "plus")
}
.sheet(isPresented: self.$sheetIsPresented)
{
VStack
{
Form
{
Section(header: Text("Section"))
{
DisclosureGroup("Outer Disclosure Group", isExpanded: self.$outerDisclosureIsExpanded)
{
ForEach(1...20, id: \.self)
{
index in Text("Value \(index)")
}
DisclosureGroup("Inner Disclosure Group", isExpanded: self.$innerDisclosureIsExpanded)
{
Text("Text")
Button("Button")
{
print("Button Pressed")
}
}
}
}
}
}
}
}
}
默认情况下,
.sheet
似乎是ScrollView
,因为当DisclosureGroup
的列表长于屏幕上可以显示的列表时,您可以向上滚动以查看底部。我想这样做,以便当内部 DisclosureGroup
展开并且其项目不在屏幕上时,ScrollView
向上滚动,以便可以看到内部 DisclosureGroup
的完整内容,如下所示:
我尝试用
VStack
和 ScrollViewReader
将 proxy
包裹在 ScrollView
中,将 id
的 Button
设置在内部 DisclosureGroup
内并执行以下操作:
withAnimation
{
proxy.scrollTo("Button", anchor: .top)
}
但是它改变了我的
List
的格式并且也不起作用。有谁知道我怎样才能做到这一点?
正如您提到的,滚动可以通过使用 ScrollViewReader 来实现。将 ScrollViewReader 保留为最外层视图不会影响列表格式。将 id 添加到按钮并在scrollTo 方法中使用相同的 id。
ScrollViewReader { proxy in
Form {
Section(header: Text("Section")) {
DisclosureGroup("Outer Disclosure Group", isExpanded: self.$outerDisclosureIsExpanded) {
ForEach(1...20, id: \.self) {
index in Text("Value \(index)")
}
DisclosureGroup("Inner Disclosure Group", isExpanded: self.$innerDisclosureIsExpanded) {
Text("Text")
Button("Button") {
print("Button Pressed")
}
.id("ButtonID")
}
}
}
}
.onChange(of: self.innerDisclosureIsExpanded) { _, newValue in
if innerDisclosureIsExpanded {
withAnimation {
proxy.scrollTo("ButtonID")
}
}
}
}