0

I am coding a SwiftUI view file that prompts the user to enter their date of birth. After all fields have been appropriately entered a navigation button appears to navigate to the next step. My only problem is when the button appears it shifts all the text included in the HStack to the left. How do I add the button without shifting the text? I tried making a separate file for the button and called that file instead but it made all the text disappear.

I tried using spacers, it makes the text shift less but I don't want it to shift at all.

(I am very new to Swift any help is greatly appreciated)

HStack {
    Spacer(minLength: 50)
    Spacer(minLength:10)
                
    VStack(alignment: .leading) {
        Text("Enter")
            .font(Font.custom("Staatliches-Regular", size: 30))
            .foregroundColor(Color.white)
            .kerning(7.2)
        
        Text("Your")
             .font(Font.custom("Staatliches-Regular", size: 30))
             .foregroundColor(Color.white)
             .kerning(7.2)
             
        Text("Birthday")
             .font(Font.custom("Staatliches-Regular", size: 30))
             .foregroundColor(Color.white)
             .kerning(7.2)
    }
    .padding(.leading, -180)
    .padding(.bottom, 100)
    .padding()
            
    Spacer()
            
    if !day.isEmpty && !month.isEmpty && !year.isEmpty {
        Button(action: {
            // Action when the button is tapped
        }) {
               Image(systemName: "arrow.right.circle.fill")
                   .resizable()
                   .frame(width: 50, height: 50).foregroundColor(Color.white)
            }
    }
    Spacer()
}
unobatbayar
  • 1,223
  • 1
  • 10
  • 24
Sam
  • 11
  • 3

1 Answers1

1

Seems it's very hard to achieve because Spacer() and HStack are dynamically changing the alignment.

However, we could solve it by making the button invisible and untouchable when conditions aren't met. This way, the items' alignment stay fixed in the same position; No movement at all when button appear/dissapear.

@State private var showButton = false
    
    var body: some View {
        HStack {
            Spacer(minLength: 50)
            Spacer(minLength:10)
            
            VStack(alignment: .leading) {
                Text("Enter")
                    .font(Font.custom("Staatliches-Regular", size: 30))
                    .foregroundColor(Color.white)
                    .kerning(7.2)
                
                Text("Your")
                    .font(Font.custom("Staatliches-Regular", size: 30))
                    .foregroundColor(Color.white)
                    .kerning(7.2)
                
                Text("Birthday")
                    .font(Font.custom("Staatliches-Regular", size: 30))
                    .foregroundColor(Color.white)
                    .kerning(7.2)
            }
            .padding(.leading, -180)
            .padding(.bottom, 100)
            .padding()
            
            Spacer()
            
            showButton = !day.isEmpty && !month.isEmpty && !year.isEmpty

            Button(action: {
                // Action when the button is tapped

            }) {
                Image(systemName: "arrow.right.circle.fill")
                    .resizable()
                    .frame(width: 50, height: 50).foregroundColor(Color.white)
            }
            .opacity(showButton ? 1 : 0) // Make it invisibile
            .allowsHitTesting(showButton) // Disable user interaction 
            
            Spacer()
        }
    }

Hope it helps.

unobatbayar
  • 1,223
  • 1
  • 10
  • 24
  • 1
    Thank you for this! While updating my code to this gave me an error, the idea steered me in the right direction. To fix it I made an updateShowButton() method that uses an if statement to check the "emptiness" of the day month and year inputs. I then called the method after every TextField and conditionally checked the boolean variable in order to determine the opacity of the button! – Sam Jul 20 '23 at 07:40