1

I have the following code:

HStack(alignment: VerticalAlignment.top) {
    Button("x"){
        self.errorText = ""
    }
    //Spacer()
}

I need to locate button on the top. But button is still on the center of HStack view.

enter image description here

What I did wrong?

PS: Using Spacer() in this place is not solution for me. I need exactly alignment.


NOT NECESSARY PART:

@State var errorText: String = "Some long error text long long long long long long long long long long long long long long long long long long long long"

        VStack{
            Spacer()
            HStack{
                Text("Error: \(errorText)")
                Spacer()
                HStack(alignment: VerticalAlignment.top) {
                    Button("x"){
                        self.errorText = ""
                    }
                    //Spacer()
                }
            }
            .frame(minHeight:10)
            .padding(.all, 5)
        }

I don't know height of the VStack (HStack parent), because of I don't know size of the error text;

Spacer() is not solution because of it's makes VStack height to the window height.

7
  • The parameter alignment: VerticalAlignment.top is for subviews, not the for HStack itself. It as a subview of its parent is aligned according to parent alignment. Commented Nov 23, 2019 at 16:13
  • @Asperi, button is subview of HStack, but it's located on the center, but not on the top of HStack. I need to locate button on the top. Commented Nov 23, 2019 at 16:56
  • If the button is the only item in the HStack the HStack is tighten to its content, so to size of button. Alignment means between internal items, ie. center all internal items or align by vertical edge all internal items, but if item is the only one... what is to align? Commented Nov 23, 2019 at 17:00
  • @Asperi, Oh, that's the reason. I understood now. In this case I need to make HStack to have a height of parent view. How can I do this? Commented Nov 23, 2019 at 17:02
  • Look as example of non-trivial layout here How to prevent a Spacer to make a VStack greedly grow beyond necessary? Commented Nov 23, 2019 at 17:04

3 Answers 3

6

You should align the outer HStack instead. Also the inner one is useless. So you can get rid of it.

VStack{
    Spacer()
    HStack(alignment: .top) {
        Text("Error: \(errorText)")
        Spacer()
        Button("x"){ self.errorText = "" }
    }
    .frame(minHeight:10)
    .padding(.all, 5)
}
Sign up to request clarification or add additional context in comments.

Comments

4

I have found that the alignment property in the HStack initializer rarely works how you expect.

Using HStack Alignment (No Effect)

VStack {
                HStack(alignment: .bottom, content: {
                    Text("Left").background(.red)
                    Text("Right").background(.green)
               })
               .frame(maxWidth: .infinity)
               .frame(height: 100)
               .background(.blue)
            }

enter image description here

Using Frame Modifier (Works)

A more reliable way of setting the cross-axis alignment in an HStack is to use the .frame modifier like this:

VStack {
                HStack(alignment: .center, content: {
                    Text("Left").background(.red)
                    Text("Right").background(.green)
               })
               .frame(maxWidth: .infinity)
               .frame(height: 100, alignment: .bottom) // Add this
               .background(.blue)
            }

enter image description here

Comments

0

try with alignment .firstTextBaseline

It will align top of the text on the first lines.

VStack{
  
   HStack(alignment: .firstTextBaseline) {
            Text("Error: \(errorText)")
            Button("x"){ self.errorText = "" }
        }
        .padding()
    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.