1

I am trying to figure out how to retrieve the size of this HStack to auto calculate dividing the frame into 3. The plan is to set a colored bar below the active screen header, please see picture example below.

VStack{
      HStack{
          Text("Overview").fontWeight(.black)
          Spacer()
          Text("Bio").fontWeight(.black)
          Spacer()
          Text("Location").fontWeight(.black)
      }
}

Gives me where I am trying to figure out the exact size of the HStack HStack size

My end goal is to achieve this.

desired outcome

Rohit Makwana
  • 4,337
  • 1
  • 21
  • 29
bain
  • 335
  • 1
  • 6
  • 17

4 Answers4

2

Wrap the HStack in GeometryReader

GeometryReader { g in
  HStack {
    Text("Overview").frame(width: g.size.width / 3)
    Text("Bio").frame(width: g.size.width / 3)
    Text("Location").frame(width: g.size.width / 3)
  }
}

https://developer.apple.com/documentation/swiftui/geometryreader

Gil Birman
  • 35,242
  • 14
  • 75
  • 119
2

Try below Code

ContentView

struct ContentView: View {

    @State var linePlaceType : LinePlace = .leading
    var selectedColor : Color = .purple
    var defaultColor : Color = .gray

    var body: some View {

        GeometryReader { g in
           VStack {
               HStack {

                    Button(action: {
                        self.linePlaceType = .leading
                    }) {
                        TextView(text: "Overview", textColor: self.getColorForText(.leading)).frame(width: g.size.width / 3)
                    }

                    Button(action: {
                        self.linePlaceType = .center
                    }) {
                        TextView(text: "Bio", textColor: self.getColorForText(.center)).frame(width: g.size.width / 3)
                    }

                    Button(action: {
                        self.linePlaceType = .trailing
                    }) {
                        TextView(text: "Location", textColor: self.getColorForText(.trailing)).frame(width: g.size.width / 3)
                    }
                }.frame(height: 40)
                .background(self.defaultColor.opacity(0.2))

                ZStack(alignment: self.linePlaceType.alignment) {

                    LineView().frame(width: g.size.width, height: 5).background(self.defaultColor)
                    LineView().frame(width: g.size.width / 3, height: 5).background(self.selectedColor)
                }.offset(x: 0, y: -12)
            }
        }
    }

    func getColorForText(_ linePlaceType: LinePlace) -> Color {

        if (linePlaceType == self.linePlaceType) {
            return self.selectedColor
        }
        else {
           return self.defaultColor
        }
    }
}

LineView

struct LineView: View {
    var body: some View {
       VStack {
            EmptyView()
        }
    }
}

TextView

struct TextView: View {

    let text : String?
    let textColor: Color?

    var body: some View {
        VStack {
            Text(self.text!)
            .font(.headline)
            .foregroundColor(self.textColor!)
        }
    }
}

enum : LinePlace

enum LinePlace {
    case leading
    case center
    case trailing
}

extension LinePlace {

    var alignment: Alignment {
        switch self {
        case .leading:
            return .leading
        case .center:
            return .center
        case .trailing:
            return .trailing
        }
    }
}

Output:

enter image description here

Rohit Makwana
  • 4,337
  • 1
  • 21
  • 29
  • this is somewhat what I am looking for but notice the misplacing under "Overview" – bain Jan 09 '20 at 03:56
  • @kontiki is you solution posted here still relevant for the newest version of Xcode. Its seems a bit complex for me but I have been trying to break it down the past couple of days to no avail. Getting a ton of errors in my Xcode https://stackoverflow.com/questions/56505043/how-to-make-view-the-size-of-another-view-in-swiftui// – bain Jan 09 '20 at 04:06
0

How about this one :

      HStack{
    Spacer().overlay(Text("OverView").bold())
    Spacer().overlay(Text("Bio").bold())
    Spacer().overlay(Text("Location").bold())
    }
E.Coms
  • 11,065
  • 2
  • 23
  • 35
0

Also you can use this library GeometryReaderStacKView to get the dimensions directly from the stack without the need to wrap your stack in a geometry reader

heres an example:

// notice the g parameter variable (GeometryProxy) holding the dimensions of the view

 
 // for HStack
 GHStack(alignment: .center, spacing: 0) { (g) in

     Color.green.frame(width: g.width/2, height: g.height/2)
     Color.yellow.frame(width: g.width/2, height: g.height/2)

 }.frame(width: 600, height: 400)
kc ochibili
  • 3,103
  • 2
  • 25
  • 25