Hoshi
Hoshi

Reputation: 607

How to draw SwiftUI Rectangles on a static baseline?

I am trying to create a balance control using 2 rectangles that represent the left and right pan value of a sound. As a start, I'm using a slider to input the values. No matter what I've done with Geometry and baseline and alignment, I cannot get the rectangles to sit on a floor. They insist on floating in space. I want to change the height, but not from the middle out!

import Foundation
import SwiftUI

struct PanView: View {
  @Binding var value: Double
    
    var body: some View {
        HStack(spacing: 10) {
          leftBar
          rightBar
        }
    }
    
    private var leftBar: some View {
      Rectangle()
        .fill(Color(.green))
        .frame(width: barWidth,
               height: abs(value - 50),
               alignment: .bottom)
    }
    
    private var rightBar: some View {
      Rectangle()
        .fill(Color(.red))
        .frame(width: barWidth,
               height: abs(value + 50),
               alignment: .bottom)
    }
    
    private var barWidth: CGFloat {
      return 50 // Adjust the width as per your preference
    }
  }

struct PanView_Used: View {
  @State private var barValue:Double = 0.0
  
  var body: some View {
    VStack {
      Text("Bar Graph at \(Int(barValue))")
        .font(.title)
      
      PanView(value: $barValue)
      
      Slider(value: $barValue, in: -50...50, step:Double.Stride(1), onEditingChanged: {e in})
    }
  }
}

struct  PV_Previews: PreviewProvider {
  static var previews: some View {
    PanView_Used()
  }
}

The horrid results are shown below. How can I get these things to sit still??

    

Upvotes: 0

Views: 121

Answers (1)

Yrb
Yrb

Reputation: 9665

You didn't give it any alignments, so it defaulted. For HStacks, that means centered vertically. VStacks default to center horizontally. Adding appropriate alignments tames the views. Comments in code:

struct PanView: View {
    @Binding var value: Double
    
    var body: some View {
        // bottom align this HStack
        HStack(alignment: .bottom, spacing: 10) {
            leftBar
            rightBar
        }
    }
    
    ...

}

struct PanView_Used: View {
    @State private var barValue:Double = 0.0
    
    var body: some View {
        VStack {
            Text("Bar Graph at \(Int(barValue))")
                .font(.title)
            
            PanView(value: $barValue)
                // Frame this since you know the max height already, and bottom align it.
                .frame(height: 100, alignment: .bottom)
            
            Slider(value: $barValue, in: -50...50, step:Double.Stride(1), onEditingChanged: {e in})
        }
    }
}

Edit:

On the HStack in Pan view works as well.

struct PanView: View {
    @Binding var value: Double
    
    var body: some View {
        // bottom align this HStack
        HStack(alignment: .bottom, spacing: 10) {
            leftBar
            rightBar
        }
                // Frame this since you know the max height already, and bottom align it.
                .frame(height: 100, alignment: .bottom)

    }

enter image description here

Upvotes: 1

Related Questions