我有一个视图,其中有几个可折叠的菜单。为了最大化空间,并且不需要滚动,我希望用户一次展开一个菜单,其他菜单应该自动折叠。请查看下面的屏幕截图和代码,它们不具有此功能。屏幕截图#1:“属性信息”菜单最初展开为
屏幕截图#2:“财产信息”和“财务”菜单均已展开。一次只能展开一个菜单,而其他菜单处于折叠状态
第一个
lndjwyie1#
考虑以下简单方法:在你的AnalyzeView中创建一个@State变量,名为expandedId,类型为UUID。通过绑定将其共享到你的两个子视图中。在子视图中,当你展开时,将此id设置为存储在你的子视图中的id。在你的子视图中响应此id的更改,如果它们与存储的id不匹配,则将collapsed变量设置为true。
AnalyzeView
@State
expandedId
UUID
collapsed
struct Collapsible_main<Content: View>: View { @Binding var expandedId: UUID // add this @State var label: () -> Text @State var content: () -> Content @State private var collapsed: Bool = false private let id = UUID() // add this var body: some View { VStack { Button( action: { self.collapsed.toggle() if !self.collapsed{ self.expandedId = self.id } }, label: { HStack { self.label() Spacer() Image(systemName: self.collapsed ? "chevron.down" : "chevron.up") } .padding(.bottom, 1) .background(Color.white.opacity(0.01)) } ) .buttonStyle(PlainButtonStyle()) VStack { self.content() } .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: collapsed ? 0 : .none) .clipped() // .animation(.easeOut) .transition(.slide) } .onChange(of: expandedId) { newValue in if newValue != self.id{ self.collapsed = true } } } } struct Collapsible_other<Content: View>: View { @Binding var expandedId: UUID // add this @State var label: () -> Text @State var content: () -> Content @State private var collapsed: Bool = true private let id = UUID() // add this var body: some View { VStack { Button( action: { self.collapsed.toggle() if !self.collapsed{ expandedId = self.id } }, label: { HStack { self.label() Spacer() Image(systemName: self.collapsed ? "chevron.down" : "chevron.up") } .padding(.bottom, 1) .background(Color.white.opacity(0.01)) } ) .buttonStyle(PlainButtonStyle()) VStack { self.content() } .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: collapsed ? 0 : .none) .clipped() // .animation(.easeOut) .transition(.slide) } .onChange(of: expandedId) { newValue in if newValue != self.id{ self.collapsed = true } } } } struct AnalyzeView: View { @State var listingValue: Double = 200000 @State var unitsValue: Double = 2 @State var sqftValue: Double = 3000 @State var downPaymentValue: Double = 100000 @State var loanValue: Double = 10000 @State var pmiValue: Double = 700 @State var interestValue: Double = 0.02 @State var closingValue: Double = 14000 @State private var expandedId = UUID() var body: some View { VStack { ZStack() { Image("analyze_property") .resizable() // .aspectRatio(contentMode: .fit) .scaledToFit() RoundedRectangle(cornerRadius: 30, style: .continuous) .fill(.blue) .opacity(0.8) .frame(width: 300, height: 170) VStack { Image("gauge") Text("Analyze") .foregroundColor(.white) .font( .largeTitle .weight(.bold) ) Text("Return On Investment") .foregroundColor(.white) } } Collapsible_main( // pass the id on expandedId: $expandedId, label: { Text("Property Information").font(.largeTitle) }, content: { VStack(spacing: 20) { Group { Text("Enter your property info below. The more data you provide the better we can analyze.").frame(maxWidth: .infinity, alignment: .leading).fixedSize(horizontal: false, vertical: true) } Text("Listing Price") Slider(value: $listingValue, in: 0...10000000, step: 1){ } minimumValueLabel: {Text("0")} maximumValueLabel: {Text("$10M")} .background(Color.gray.brightness(0.4)).padding(.trailing, 50).padding(.leading, 50) //Text("\(listingValue, specifier: "%.0f")") Text("Total Units") Slider(value: $unitsValue, in: 0...20, step: 1){ } minimumValueLabel: {Text("0")} maximumValueLabel: {Text("20")}.background(Color.gray.brightness(0.4)).padding(.trailing, 50).padding(.leading, 50) //Text("\(unitsValue, specifier: "%.0f")") Text("Square Feet") Slider(value: $sqftValue, in: 0...15000, step: 1){ } minimumValueLabel: {Text("0")} maximumValueLabel: {Text("15K")}.background(Color.gray.brightness(0.4)).padding(.trailing, 50).padding(.leading, 50) //Text("\(sqftValue, specifier: "%.0f")") } } ) Collapsible_other( //pass the id on expandedId: $expandedId, label: { Text("Financials").font(.largeTitle) }, content: { VStack { Text("Enter your financial data below.") Group { Text("Down Payment") Slider(value: $downPaymentValue, in: 0...10000000, step: 1).padding(.trailing, 50).padding(.leading, 50) Text("\(downPaymentValue, specifier: "%.0f")") } Group { Text("Loan Amount") Slider(value: $loanValue, in: 0...10000000, step: 1).padding(.trailing, 50).padding(.leading, 50) Text("\(loanValue, specifier: "%.0f")") } Group { Text("PMI") Slider(value: $pmiValue, in: 0...5000, step: 1).padding(.trailing, 50).padding(.leading, 50) Text("\(pmiValue, specifier: "%.0f")") } Group { Text("Interest Rate") Slider(value: $interestValue, in: 0...1, step: 0.01).padding(.trailing, 50).padding(.leading, 50) Text("\(interestValue, specifier: "%.0f")") } Group { Text("Closing Cost/Fees") Slider(value: $closingValue, in: 0...30000, step: 1).padding(.trailing, 50).padding(.leading, 50) Text("\(closingValue, specifier: "%.0f")") } } } ) Spacer() } } }
1条答案
按热度按时间lndjwyie1#
考虑以下简单方法:
在你的
AnalyzeView
中创建一个@State
变量,名为expandedId
,类型为UUID
。通过绑定将其共享到你的两个子视图中。在子视图中,当你展开时,将此id设置为存储在你的子视图中的id。在你的子视图中响应此id的更改,如果它们与存储的id不匹配,则将collapsed
变量设置为true。