3

How can I set the width of a window that shall be resizable with a Button in MacOS SwiftUI? I tried with the frame modifier, but that sets the width permanently. I want the user to be able to drag the Sitze with the mouse and set a predefined size via a Button.

struct ResizeTest: App {
    var body: some Scene {
        WindowGroup {
          ContentView()
            .frame(minWidth: 200, maxWidth: 1000)            
            .padding(0)
        }
        .defaultSize(width: 300, height: 400)
        .windowResizability(.contentSize)
    }
}

struct ContentView: View {
  @State var width = 400.0
  
  var body: some View {
    VStack (alignment: .center) {
      Text("width: \(width)")
      Button("600"){ width = 600}
    }
    .frame(width:width )
    .background(Color.green)
  }
}
2
  • take out the line .frame(minWidth: 200, maxWidth: 1000) Commented Jan 1, 2023 at 12:49
  • I need a minWidth and MaxWidth of the window. But removing it, doesn't solve the problem, that the window is NOT resizable, as it shall be. Commented Jan 1, 2023 at 12:56

1 Answer 1

3

Ok that was a little tricky ... its a bit of a hack, but it does work: The buttons set both minWidth and maxWidth to the desired value to force a resize of the window, then reset the values back to the full possible resize range (200-1000) after 0.5 secs.

@main
struct ResizeTest: App {
    var body: some Scene {
        WindowGroup {
          ContentView()
        }
        .windowResizability(.contentSize)
    }
}

struct ContentView: View {
    @State var minWidth = 200.0
    @State var maxWidth = 1000.0

    var body: some View {
        GeometryReader { geo in
            VStack (alignment: .center) {
                
                Text("Current width: \(geo.size.width.formatted())")
                    .frame(maxWidth: .infinity)
                
                Button("400"){
                    minWidth = 400 // set
                    maxWidth = 400
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // reset after 0.5 secs
                        minWidth = 200
                        maxWidth = 1000
                    }
                }
                Button("600"){
                    minWidth = 600 // set
                    maxWidth = 600
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // reset after 0.5 secs
                        minWidth = 200
                        maxWidth = 1000
                    }
                }
            }
        }
        .frame(height: 100)
        .frame(minWidth: minWidth, maxWidth: maxWidth)
        .background(Color.green)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.