NEW: Learn to build the incredible iOS 15 Weather app today! >>

[FIXED-ish] Position view at the bottom of another view -- shouldn't this be easy?

Forums > SwiftUI

(The fix-ish was to move the .frame() modifier below .background() modifier. The full fix would involve me getting a Hogwart's certificate in SwiftUI. Jeez this stuff is confusing.)

I just want the two sliders to sit at the bottom of the square. If I put a frame with alignment: .bottom, nothing happens. If I put a .frame(maxHeight: .infinity, alignment: .bottom), the sliders go where I want them, but then the background covers up the rest of the square. So, I have three primary questions:

  1. Is there an easy way to put the sliders at the bottom without calculating sizes and absolute positioning?
  2. Am I totally going about this all wrong? Usually when something is 10x harder than it should be, I find that I'm missing some important concept about the way the tools work
  3. What's your personal favorite "How do you do this thing that should be trivial?" site for SwiftUI?

struct TrundleCharacteristicsView: View {
    @State private var wheelRadius = 0.75
    @State private var wheelRotation = 1.0
    @State private var penPosition = 1.0

    var wheelIndicatorAngle: Angle {
        let a = wheelRotation / 5.0
        let b = a * Double.pi
        let c = b / 2.0
        return Angle(radians: c)
    }

    let darkBlue = Color(NSColor.blue.withAlphaComponent(0.5))

    var body: some View {
        ZStack {
            Circle()    // Full-scale indicator
                .strokeBorder(darkBlue, lineWidth: 2)
                .aspectRatio(1.0, contentMode: .fit)

            Circle()    // Current scale indicator
                .strokeBorder(Color.blue, lineWidth: 3)
                .aspectRatio(1.0, contentMode: .fit)
                .scaleEffect(wheelRadius)

            Rectangle() // Pen position indicator
                .fill(Color.blue)
                .cornerRadius(5)
                .border(darkBlue, width: 1)
                .frame(width: 4, height: 100)
                .offset(y: -50)
                .scaleEffect(CGSize(width: 1, height: penPosition), anchor: .init(x: 0.5, y: 0.5))
                .rotationEffect(wheelIndicatorAngle, anchor: .init(x: 0.5, y: 0.5))

            VStack {
                Slider(value: $wheelRadius, in: 0...1.0)
                    .controlSize(.mini)

                Slider(value: $penPosition, in: 0...1.0)
                    .controlSize(.mini)
            }
//            .frame(maxHeight: .infinity, alignment: .bottom)
            .background(Color.black)
        }
        .frame(width: 200, height: 200)
    }
}

   

Did you try

VStack {
  Spacer() //pushes all to the bottom
  Slider(value: $wheelRadius, in: 0...1.0)
    .controlSize(.mini)

  Slider(value: $penPosition, in: 0...1.0)
    .controlSize(.mini)
}

   

Sad to say, that does the same thing as frame(maxWidth: .infinity), meaning, it causes the black background to cover everything else

   

I'm not sure if this is want you want?

var body: some View {
  VStack {
    ZStack {
      Color.black
      Circle()    // Full-scale indicator
        .strokeBorder(darkBlue, lineWidth: 2)
        .aspectRatio(1.0, contentMode: .fit)
      Circle()    // Current scale indicator
        .strokeBorder(Color.blue, lineWidth: 3)
        .aspectRatio(1.0, contentMode: .fit)
        .scaleEffect(wheelRadius)

      Rectangle() // Pen position indicator
        .fill(Color.blue)
        .cornerRadius(5)
        .border(darkBlue, width: 1)
        .frame(width: 4, height: 100)
        .offset(y: -50)
        .scaleEffect(CGSize(width: 1, height: penPosition), anchor: .init(x: 0.5, y: 0.5))
        .rotationEffect(wheelIndicatorAngle, anchor: .init(x: 0.5, y: 0.5))
    }.frame(width: 200, height: 200)

    VStack {
      Slider(value: $wheelRadius, in: 0...1.0)
        .controlSize(.mini)

      Slider(value: $penPosition, in: 0...1.0)
        .controlSize(.mini)
    }
  }
}

   

This is what I'm trying to accomplish. I could have drawn it with crayons easier than with Swift 😆

   

Okay, now I see.

This works for your VStack. Your original code with this VStack.

VStack(spacing: 0) {
    Spacer()
    Slider(value: $wheelRadius, in: 0...1.0)
        .controlSize(.mini)
        .background(Color.black)
    Slider(value: $penPosition, in: 0...1.0)
        .controlSize(.mini)
        .background(Color.black)
}

1      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Learn the most up-to-date techniques and strategies for testing new and legacy Swift code in this free practical course for iOS devs who want to become complete Senior iOS Developers.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.