zumzum
zumzum

Reputation: 20268

SwiftUI: align views in different HStacks?

I have the following view for each of the cells used in the List view....:

var body: some View {

    VStack {
        
        HStack {
            Text("item: \(item.name)")
            Text("Some text")
            Spacer()
        }
        
        HStack {
            Image(systemName: "squareshape.fill")
                .resizable()
                .frame(width: 30, height: 30)
            
            Spacer()
        }
        
    }

}

Looks like this:

enter image description here

I want to align the black square to the Some text leading edge found in the previous HStack. I annotated the image to visually show where the black square should land for clarity.

I have looked at a couple of similar questions that might have the solution in it but I haven't been able to apply what I saw to my need here yet. I believe I need to use alignment guides, but, I am not sure how to actually apply such change.

I think I could break the layout out differently where I could be using VStacks etc... but, I want to know how to tell a view to align itself to another in this case across HStacks...

How could I accomplish what outlined?

Upvotes: 4

Views: 2333

Answers (1)

Asperi
Asperi

Reputation: 258541

Here is a demo of possible approach - based on custom alignment guides, ie. applying same custom alignment guide to different views makes them aligned to/by that guide. (Actually you don't need second HStack for this scenario).

Tested with Xcode 12.5 / iOS 14.5

demo

struct ContentView: View {
    var body: some View {
        List(0..<10) {
            RowView(item: $0)
        }
    }
}

extension HorizontalAlignment {
   private enum MyLeadingAlignment: AlignmentID {
      static func defaultValue(in dimensions: ViewDimensions) -> CGFloat {
         return dimensions[HorizontalAlignment.leading]
      }
   }
   static let myLeading = HorizontalAlignment(MyLeadingAlignment.self)
}

struct RowView: View {
    let item: Int
    var body: some View {

        VStack(alignment: .myLeading) {
            HStack {
                Text("item: \(item)")
                Text("Some text")
                    .alignmentGuide(.myLeading) { $0[.leading] } // << here !!
                Spacer()
            }
            Image(systemName: "squareshape.fill")
                .resizable()
                .frame(width: 30, height: 30)
                .alignmentGuide(.myLeading) { $0[.leading] } // << here !!
        }
    }
}

Upvotes: 6

Related Questions