Frank Yellin
Frank Yellin

Reputation: 11230

Forcing a View to the bottom right of View in SwiftUI

I'm teaching myself SwiftUI by taking the 2020 version of Stanford's CS193p posted on YouTube.

I'd like to have a ZStack with a check box in the bottom right. This code puts the check mark right in the middle of the View.

ZStack {
    .... stuff ....
    Text("✓")
}

Much to my surprise, this code puts the check mark in the top left corner of the View. (My mental model of GeometryReader is clearly wrong.)

ZStack {
   .... stuff ...
   GeometryReader { _ in Text("✓") }
}

I can't use ZStack(alignment: .bottomTrailing) { ... } as suggested in a different StackOverflow answer, as I want the alignment to apply only to the text, and not to anything else.

Is there any way to get the check mark on the bottom right? I'm trying to avoid absolute offsets, since I want my code to work no matter what the size of the ZStack view. Also, is there a good tutorial on layout so that I can figure out the answer to these questions myself?

[In case you're wondering. I'm playing around with Homework Assignment 3. I'm adding a "cheat mode" where if there is a matchingSet on the board, it marks them with a small check mark.]

Upvotes: 2

Views: 3103

Answers (3)

Samuel Folledo
Samuel Folledo

Reputation: 493

Using VStack overlaying in trailing and using VStack with spacer worked for me like so

ProgressBar(progress: progressValue)
    .overlay(alignment: .trailing) {
        VStack {
            Spacer()
                .frame(maxHeight: .infinity)

            Color.black
                .clipShape(.circle)
                .frame(width: reader.size.width / 2.5)
        }
    }

Upvotes: 0

Pranav Kasetti
Pranav Kasetti

Reputation: 9915

I would say that it's possible if you know the size of the Text and the largest subview in the ZStack.

In the example below I've used 40 as the Text width and 20 as the Text height, and 200 (square) for the largest Color subview. You can then calculate the subview offsets using relative offsets and layout guides.

This is useful if you don't want to expand the Text to fill the container like the above answer.

struct ColorsView: View {
  var body: some View {
    ZStack(alignment: .center) {
      Color.red.frame(width: 200,
                      height: 200,
                      alignment: .center)
      Text("Bye")
      Text("Hello").frame(width: 40, height: 20)
        .alignmentGuide(HorizontalAlignment.center, computeValue: { dimension in
          -60
        })
        .alignmentGuide(VerticalAlignment.center, computeValue: { dimension in
          -80
        })
    }
  }
}

Upvotes: 1

Adam
Adam

Reputation: 5105

Try applying

.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomTrailing)

to Text.

Upvotes: 5

Related Questions