Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Save and Restore HSplitview Position in SwiftUI

Tags:

swiftui

I would like to be able to save and restore the position of a SwiftUI splitView but I can’t figure out how to do it. I haven’t found any examples and the documentation doesn’t have any info. I have the following:

struct ContentView: View {
   var body: some View {
      GeometryReader{geometry in
         HSplitView(){
            Rectangle().foregroundColor(.red).layoutPriority(1)
            Rectangle().foregroundColor(.green).frame(minWidth:200, idealWidth: 200, maxWidth: .infinity)
         }.frame(width: geometry.size.width, height: geometry.size.height)
      }
   }
}

Does anyone know how I can get the position of the slider so it can be saved, and also restored on startup? Thanks!

like image 849
Peter Avatar asked Oct 20 '25 15:10

Peter


1 Answers

Here's a workaround I've been using. It uses a plain HStack and a draggable view to recreate what HSplitView does. You can save then save the draggableWidth state however you want.

public struct SlideableDivider: View {
    @Binding var dimension: Double
    @State private var dimensionStart: Double?

    public init(dimension: Binding<Double>) {
        self._dimension = dimension
    }
    
    public var body: some View {
        Rectangle()
            .fill(.gray)
            .frame(width: 2)
            .onHover { inside in
                if inside {
                    NSCursor.resizeLeftRight.push()
                } else {
                    NSCursor.pop()
                }
            }
            .gesture(drag)
    }
    
    var drag: some Gesture {
        DragGesture(minimumDistance: 10, coordinateSpace: CoordinateSpace.global)
            .onChanged { val in
                if dimensionStart == nil {
                    dimensionStart = dimension
                }
                let delta = val.location.x - val.startLocation.x
                dimension = dimensionStart! + Double(delta)
            }
            .onEnded { val in
                dimensionStart = nil
            }
    }
}
...
struct ContentView: View {
    @AppStorage("ContentView.draggableWidth") var draggableWidth: Double = 185.0
    var body: some View {

        // This will be like an HSplitView
        HStack(spacing: 0) {

            Text("Panel 1")
            .frame(width: CGFloat(draggableWidth))
            .frame(maxHeight: .infinity)
            .background(Color.blue.opacity(0.5))
            
            SlideableDivider(dimension: $draggableWidth)
            
            Text("Panel 2")
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.red.opacity(0.5))
            
        }
        .frame(maxWidth: .infinity)
    }
}
like image 118
Rob N Avatar answered Oct 22 '25 04:10

Rob N



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!