what I'm after is a little bit different.
Please include the explicit description about what you really want to do in your opening post.
I got some error at the switch case let part
You should better include the whole error message to reduce reader's time.
As you are not showing whole code (missing
HSplitView or
VSplitView), it takes more time to test your code.
You make your
SingleView as to take a Binding, so you need to pass a Binding to
SingleView.init(content:).
To achieve this, you may need to construct Bindings to
splittableContentLeft and
splittableContentRight.
You can construct sort of computed Bindings in some ways, but as far as I tried, a simple implementation using computed properties did not work as expected when indirect cases are nested.
To make things stable, you can use a reference type instead.
SplittableContent.swiftCode Block | import Combine |
|
| enum SplittingState { |
| case single |
| case hSplit |
| case vSplit |
| } |
| class SplittableContent: ObservableObject { |
| @Published var splittingState: SplittingState = .single |
| @Published var firstContent: SplittableContent? |
| @Published var secondContent: SplittableContent? |
| |
| private var firstObserver: AnyCancellable? |
| private var secondObserver: AnyCancellable? |
| init() { |
| firstObserver = $firstContent.sink{_ in self.objectWillChange.send()} |
| secondObserver = $secondContent.sink{_ in self.objectWillChange.send()} |
| } |
| } |
| extension SplittableContent { |
| func copy()->SplittableContent { |
| let newInstance = SplittableContent() |
| newInstance.splittingState = self.splittingState |
| newInstance.firstContent = self.firstContent?.copy() |
| newInstance.secondContent = self.secondContent?.copy() |
| return newInstance |
| } |
| } |
SingleView.swiftCode Block | import SwiftUI |
|
| struct SingleView: View { |
| @ObservedObject var viewContent: SplittableContent |
| var body: some View { |
| VStack { |
| HStack { |
| Button(action: { |
| self.viewContent.firstContent = self.viewContent.copy() |
| self.viewContent.secondContent = self.viewContent.copy() |
| self.viewContent.splittingState = .hSplit |
| }) { |
| Text("|") |
| } |
| Spacer() |
| Button(action: { |
| self.viewContent.firstContent = self.viewContent.copy() |
| self.viewContent.secondContent = self.viewContent.copy() |
| self.viewContent.splittingState = .vSplit |
| }) { |
| Text("-") |
| } |
| }.padding([.top, .bottom],5) |
| .padding([.leading, .trailing], 10) |
| .background(Color(red: 0.5, green: 0.5, blue: 0.5)) |
| Spacer() |
| Text("Main window") |
| Spacer() |
| } |
| } |
| } |
| struct SingleView_Previews: PreviewProvider { |
| static var previews: some View { |
| SingleView(viewContent: SplittableContent()) |
| } |
| } |
ContentView.swiftCode Block | import SwiftUI |
|
| struct SplittableView: View { |
| @ObservedObject var content: SplittableContent |
| var body: some View { |
| switch content.splittingState { |
| case .single: |
| return AnyView(SingleView(viewContent: content)) |
| case .hSplit: |
| return AnyView(HSplitView { |
| SplittableView(content: self.content.firstContent!) |
| SplittableView(content: self.content.secondContent!) |
| }) |
| case .vSplit: |
| return AnyView(VSplitView { |
| SplittableView(content: self.content.firstContent!) |
| SplittableView(content: self.content.secondContent!) |
| }) |
| } |
| } |
| } |
| struct ContentView : View { |
| @EnvironmentObject var splittableContent: SplittableContent |
| |
| var body: some View { |
| VStack{ |
| Button("show") { |
| print(self.splittableContent) |
| } |
| SplittableView(content: splittableContent) |
| } |
| } |
| } |
| struct ContentView_Previews: PreviewProvider { |
| static var previews: some View { |
| ContentView() |
| .environmentObject(SplittableContent()) |
| } |
| } |