SwiftUI using the width of a view in its modifiers

I'm trying to create a rounded button with dynamic height/width. To be perfectly rounded, the corner radius must be equal to half of the button's height. Is there a way to dynamically update the corner radius used by the modifier as the view's bound's are changed?

This is what I have so far for the button's label:
Code Block HStack {		Image(systemName: "plus")		Text("Add")}.padding(.vertical, 5).padding(.horizontal).overlay(RoundedRectangle(cornerRadius: 10).stroke(lineWidth: 1))

Answered by OOPer in 616280022
You can define your own shape, and use CGRect in its implementation of path(in:).
Code Block struct CircularEndBox: Shape {    func path(in rect: CGRect) -> Path {        var path = Path()        let cornerSize: CGSize        if rect.width > rect.height {            cornerSize = CGSize(width: rect.height/2, height: rect.height/2)        } else {            cornerSize = CGSize(width: rect.width/2, height: rect.width/2)        }        path.addRoundedRect(in: rect, cornerSize: cornerSize)        return path    }}


You can use it the same way as other Shapes.
Code Block             HStack {                    Image(systemName: "plus")                    Text("Add")            }            .padding(.vertical, 5)            .padding(.horizontal)            .overlay(CircularEndBox().stroke(lineWidth: 1))



This is actually a little complex to do. You should definitely watch the great talk "SwiftUI under the hood" given by Chris Eidhof in BA: Swiftable conferece. He goes through the entire process of creating a dynamic circular button while explaining some interesting details of the framework. The video is available on Youtube.
Thanks for your reply, I'll definitely give it a watch, cheers 🙂
Accepted Answer
You can define your own shape, and use CGRect in its implementation of path(in:).
Code Block struct CircularEndBox: Shape {    func path(in rect: CGRect) -> Path {        var path = Path()        let cornerSize: CGSize        if rect.width > rect.height {            cornerSize = CGSize(width: rect.height/2, height: rect.height/2)        } else {            cornerSize = CGSize(width: rect.width/2, height: rect.width/2)        }        path.addRoundedRect(in: rect, cornerSize: cornerSize)        return path    }}


You can use it the same way as other Shapes.
Code Block             HStack {                    Image(systemName: "plus")                    Text("Add")            }            .padding(.vertical, 5)            .padding(.horizontal)            .overlay(CircularEndBox().stroke(lineWidth: 1))



That's perfect, really elegant, thanks a lot :)
SwiftUI using the width of a view in its modifiers
 
 
Q