1

I've seen a few similar examples of this such as How to correctly do up an adjustable split view in SwiftUI? and How to resize UIView by dragging from its edges? but I can't find exactly what I'm looking for that correlates correctly across to SwiftUI

I have a view that I want the user to be able to adjust the width of via a 'grab bar' on the right of the view. When the user drags this bar left (decreases view width) and to the right (increases the view width). How can I go about doing this?

In the example, RedRectangle is my view that i'm trying to adjust which comprises of a Rectangle and the Resizer which is manipulated to adjust the size. What am I doing wrong here?

Additionally, there isn't a gradual animation/transition of the frame being increased/decreased and it just seems to jump. How can I achieve this?

Reproducible example linked here:

import SwiftUI

struct ContentView: View {
    @State var resizedWidth: CGFloat?

    var body: some View {
        HStack(alignment: .center) {
            Spacer()
            RedRectangle(width: 175, resizedWidth: resizedWidth)
            Resizer()
                .gesture(
                    DragGesture()
                        .onChanged({ value in
                            resizedWidth = max(80, resizedWidth ?? 0 + value.translation.width)
                        })
                )
            Spacer()
        }
    }
}

struct RedRectangle: View {
    let width: CGFloat
    var resizedWidth: CGFloat?

    var body: some View {
        Rectangle()
            .fill(Color.red)
            .frame(width: resizedWidth != nil ? resizedWidth : width, height: 300)
            .frame(minWidth: 80, maxWidth: 400)
    }
}

struct Resizer: View {
    var body: some View {
        Rectangle()
            .fill(Color.blue)
            .frame(width: 8, height: 75)
            .cornerRadius(10)
    }
}
Nouman
  • 585
  • 1
  • 11
  • 24
  • Can you create a [mre] so we can make the exact answer you're looking for? Right now I don't know where you insert the `content()`, where `width` comes from, etc. Just a few simple views to create this basic example would really help – George Jan 17 '22 at 00:32
  • Hey @George, so the code doesn't work quite as required hence the question, but I have linked it above. When you run it, you can probably get a decent idea of what i'm trying to do – Nouman Jan 17 '22 at 02:04

1 Answers1

0
import SwiftUI

struct ContentView: View {
    let minWidth: CGFloat = 100
    @State var width: CGFloat?

    var body: some View {
        HStack(alignment: .center) {
            Spacer()
            RedRectangle(width: width ?? minWidth)
            Resizer()
                .gesture(
                    DragGesture()
                        .onChanged { value in
                            width = max(minWidth, width! + value.translation.width)
                        }
                )
            Spacer()
        }
        .onAppear {
            width = minWidth
        }
    }
}

struct RedRectangle: View {
    let width: CGFloat

    var body: some View {
        Rectangle()
            .fill(Color.red)
            .frame(width: width, height: 100)
    }
}

struct Resizer: View {
    var body: some View {
        Rectangle()
            .fill(Color.blue)
            .frame(width: 8, height: 75)
            .cornerRadius(10)
    }
}
Nouman
  • 585
  • 1
  • 11
  • 24