skip to Main Content

I’m struggling on creating two vertical bars with lines and dash box. I would like to receive some suggestion on how to do this.

This is what I’m aiming to do:

image

Currently this is my code.

import SwiftUI

struct LoadManagementItemBarView: View {
    
    let isLeft: Bool
    let userWeight: Float
    @State var progress: CGFloat
    
    var body: some View {
            ZStack(alignment: .bottom) {
                Rectangle()
                    .fill(Color.white)
                    .frame(width: 32, height: 490)
                
                Rectangle()
                    .fill(Color.positiveStappone)
                    .frame(width: 32, height: progress)
                
                VStack {
                    HStack(alignment: .center) {

                        if isLeft {
                            Text("(String(format: "%.0f", userWeight)) kg")
                        }
                        
                        Rectangle()
                            .frame(width: 38, height: 1)
                        
                        if !isLeft {
                            Text("(String(format: "%.0f", userWeight)) kg")
                        }
                    }
                    .offset(y: CGFloat(userWeight))
                    
                    Rectangle()
                        .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [10]))
                        .frame(width: 32, height: 188)
                        .offset(x: isLeft ? 24 : -23, y: -76)
                    
                    HStack(alignment: .center) {

                        if isLeft {
                            Text(" 0 kg")
                        }
                        
                        Rectangle()
                            .frame(width: 38, height: 1)
                        
                        if !isLeft {
                            Text(" 0 kg")
                        }
                    }
                    .offset(y: 11)
                }
                .offset(x: isLeft ? -24 : 23)
            }
            .shadow(color: .gray, radius: 1, x: 1, y: 1)
    }
}

struct LoadManagementItemBarView_Previews: PreviewProvider {
    static var previews: some View {
        LoadManagementItemBarView(
            isLeft: true,
            userWeight: 76,
            progress: 350
        )
    }
}

I tried to use ZStack to fit all of the UI components but I’m struggling with the offset of these component, example to modify it’s y offset by just adding a max KG to the property created.
I want it to look like in the image below.

2

Answers


  1. struct ContentView: View {
    var body: some View {
        VStack {
            Spacer()
            HStack {
                Rectangle()
                    .frame(width: 5, height: 50)
                Spacer()
                Rectangle()
                    .frame(width: 5, height: 50)
            }
            Spacer()
            HStack {
                Rectangle()
                    .frame(width: 80, height: 2)
            }
            Spacer()
        }
        .frame(width: 150, height: 100)
        .border(Color.black, style: .dashed)
    }
    

    }

    Login or Signup to reply.
  2. I would suggest you split the background bar and the marker (the dashed box) into two separate View implementations, then apply the marker as an overlay. Something like:

    private var backgroundBar: some View {
        // Implement the background bar here
    }
    
    private var marker: some View {
        Rectangle()
            .strokeBorder(
                style: StrokeStyle(
                    lineWidth: 1,
                    dash: [10]
                )
            )
            // Only the height needs to be specified
            .frame(height: myComputedHeight)
    
            // Only the y-offset needs to be specified
            .offset(y: myComputedOffset)
    }
    
    var body: some View {
        backgroundBar
            .overlay(marker, alignment: .top)
    }
    

    For iOS 15+ you probably want to use the new version of the .overlay modifier, the version I’ve used here has been deprecated.

    For the bar scaling, two possible ways to approach would be:

    • either, implement the scaling in another separate View and combine the views using an HStack
    • or, include the scaling in the backgroundBar view and then add appropriate padding (left or right) to the marker.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search