1

I have one VStack and another HStack with buttons inside. I faced problem with shrinking buttons based on their content even though I tried to set fixed width and height of Buttons.

Here is the main screen:

import Foundation
import SwiftUI
import SwiftUINavigator

struct SurveyScreenView: View, IItemView {
    
    var listener: INavigationContainer?
    @State var survey: Survey
    @State var isUp = false
    @State var isDown = false
    
    @State var widthButton: CGFloat = 100
    @State var heightButton: CGFloat = 50
    
    var body: some View {
        NavigationView {
            VStack(alignment: .leading, spacing: 32) {
                Text(survey.title)
                    .font(.title)
                Text(survey.description)
                
                VoteView( survey: $survey, isUp: $isUp, isDown: $isDown)
                
                Spacer()
            }
            .navigationBarItems(leading:
                Button(action: {
                    listener?.pop()
                }, label: {
                    Text("Feed")
                })
            )
            .navigationBarTitle(Text("Survey"))
            .navigationBarTitleDisplayMode(.inline)
            .padding()
        }
    }
}

View with Buttons in HStack

struct VoteView: View {
    
    @Binding var survey: Survey
    @Binding var isUp: Bool
    @Binding var isDown: Bool
    
    var body: some View {
        HStack(alignment: .center, spacing: 64) {
            
            VoteButton (
                isVoted: $isUp,
                counter: survey.upVotes,
                text: "YES"
            ) {
                self.isUp.toggle()
                if isUp == isDown {
                    self.isDown.toggle()
                }
            }
            
            VoteButton (
                isVoted: $isDown,
                counter: survey.downVotes,
                text: "NO"
            ) {
                self.isDown.toggle()
                if isUp == isDown {
                    self.isUp.toggle()
                }
            }
            
        }
    }
}

Cutom button view

struct VoteButton: View {
    
    @Binding var isVoted: Bool
    var counter: Int = 0
    var text: String = ""
    var clicked: (() -> Void)

    var body: some View {
        if isVoted {
            Button(action: clicked) {
                VStack(alignment: .center, spacing: 5) {
                    Text(text)
                        .font(.headline)
                    Text("\(counter)")
                        .font(.subheadline)
                }
                .foregroundColor(.white)
                .background(.blue)
                .cornerRadius(8)
                .frame(maxWidth: .infinity, minHeight: 40)
            }
            
        } else {
            Button(action: clicked)  {
                VStack(alignment: .center, spacing: 5) {
                    Text(text)
                        .font(.headline)
                    Text("\(counter)")
                        .font(.subheadline)
                }
                .foregroundColor(.blue)
                .background(.white)
                .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.blue, lineWidth: 2))
                .frame(maxWidth: .infinity, minHeight: 40)
            }
        }
    }
}

I tried several tutorials, for example. Also tried this solution.

I got the same result everywhere, like this one: bad

But I am actually expecting this result: good

2 Answers2

3

You can try below code technique and modify it according to requirements

HStack {
            Button("Yes") { }
                .foregroundColor(.white)
                .padding()
                .frame(maxWidth: .infinity)
                .background(Color.red)
                .clipShape(Capsule())

            Button("No") { }
                .foregroundColor(.white)
                .padding()
                .frame(maxWidth: .infinity)
                .background(Color.red)
                .clipShape(Capsule())
        }
        .fixedSize(horizontal: false, vertical: true)
        .padding()

enter image description here

multiverse
  • 425
  • 3
  • 13
0

You can use .frame(maxWidth: .infinity) for to stretch any view.

struct VoteButton: View {

@Binding var isVoted: Bool
var counter: Int = 0
var text: String = ""
var clicked: (() -> Void)

var body: some View {
    if isVoted {
        Button(action: clicked) {
            VStack(alignment: .center, spacing: 5) {
                Text(text)
                    .font(.headline)
                    .frame(maxWidth: .infinity)  <<<<-- This shall fix your issue
                Text("\(counter)")
                    .font(.subheadline)
                    .frame(maxWidth: .infinity)  <<<<-- This shall fix your issue
            }
            .foregroundColor(.white)
            .background(.blue)
            .cornerRadius(8)
        }
        .frame(maxWidth: .infinity)

    } else {
        Button(action: clicked)  {
            VStack(alignment: .center, spacing: 5) {
                Text(text)
                    .font(.headline)
                    .frame(maxWidth: .infinity)  <<<<-- This shall fix your issue

                Text("\(counter)")
                    .font(.subheadline)
                    .frame(maxWidth: .infinity)  <<<<-- This shall fix your issue

            }
            .foregroundColor(.blue)
            .background(.white)
            .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.blue, lineWidth: 2))
        }
        .frame(maxWidth: .infinity, minHeight: 40)
    }
}
}
Pankaj Gaikar
  • 2,357
  • 1
  • 23
  • 29