3

I am trying to figure out how to align my "Create" Button in the exact middle of my screen with my "share" button to the right of my centered "Create" Button, without using arbitrary numbers.

not centered Create button

            HStack (spacing: 40) {
                Text("Create")
                    .fontWeight(.bold)

                    .frame(width: 185, height: 40, alignment: .center)
                    .cornerRadius(50)
                    .overlay(
                        Capsule(style: .circular)
                            .stroke(Color(red: 0.879, green: 0.369, blue: 0, opacity: 1), style: StrokeStyle(lineWidth: 2)))

                Image(systemName:"square.and.arrow.up")
                    .resizable()
                    .frame(width: 25, height: 30)
                    .font(Font.title.weight(.light))

            }  .foregroundColor(Color(red: 0.879, green: 0.369, blue: 0, opacity: 1))
bain
  • 335
  • 1
  • 6
  • 17
  • see this post: https://stackoverflow.com/questions/59517327/center-item-inside-horizontal-stack/59517584#59517584 – E.Coms Jan 04 '20 at 04:31

3 Answers3

3

Here is how I would do it (no hardcoded numbers)

SwiftUI alignment center button with left another

HStack {
    Spacer()
    Text("Create")
        .fontWeight(.bold)

        .frame(width: 185, height: 40, alignment: .center)
        .cornerRadius(50)
        .overlay(
            Capsule(style: .circular)
                .stroke(Color(red: 0.879, green: 0.369, blue: 0, opacity: 1), style: StrokeStyle(lineWidth: 2)))
    Spacer()
        .overlay(
            HStack {
                Image(systemName:"square.and.arrow.up")
                    .resizable()
                    .frame(width: 25, height: 30)
                    .font(Font.title.weight(.light))
                Spacer()
            }
            .padding(.leading) // << here can be any distance to center button
        )
}
.foregroundColor(Color(red: 0.879, green: 0.369, blue: 0, opacity: 1))
Asperi
  • 228,894
  • 20
  • 464
  • 690
0

There's probably a better way, but this will do it. It just adds the action button as an overlay to the main Create button. But by using a PreferenceKey, the action button knows the size (and origin) of the Create button and can offset itself accordingly. Using rectangles here to represent the buttons so it's easier to read.

struct BoundsPreferenceKey: PreferenceKey {

  typealias Value = CGRect

  static var defaultValue: CGRect = .zero

  static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
    value = value.union(nextValue())
  }

}

struct CenteredView: View {

  let spacing: CGFloat = 40

  var body: some View {

    HStack {

      Rectangle().fill(Color.blue)
        .frame(width: 185, height: 40)
        .preference(key: BoundsPreferenceKey.self, value: CGRect(origin: .zero, size: CGSize(width: 185, height: 40)))
        .overlayPreferenceValue(BoundsPreferenceKey.self) { rect in
          Rectangle().fill(Color.green)
            .frame(width: 25, height: 30)
            .offset(x: rect.size.width/2 + self.spacing, y: 0)
      }

    }

  }

}

You could use GeometryReader to avoid specifying the height and width, but you need to specify it for the frame anyway.

Alternatively, look at a custom alignment guide.

Cenk Bilgen
  • 1,330
  • 9
  • 8
0

It could be like this:

     HStack{
            Spacer()
            Spacer().overlay(Button("Create"){}.padding(10).border(Color.blue, width: 3.0))
            Spacer()
            }
E.Coms
  • 11,065
  • 2
  • 23
  • 35