0

I followed the @swiftPunk answer it's working fine. But at the last point I stuck on my first image is not showing properly. Please check attached screenshot.

Updated Code:-

struct ImageStackRoundUpr: View {
var friendRiders = ["DTR-CentrImg.jpeg", "1frame_0_delay-0.07s", "frame_7_delay-0.07s"]
var nonFriendRiders = ["DTR-CentrImg.jpeg", "1frame_0_delay-0.07s", "frame_7_delay-0.07s"]
var body: some View {
    HStack(spacing:-10) {
        Group {
            ZStack {
                Image("DTR-CentrImg.jpeg")
                     .renderingMode(.original)
                    .resizable()
                    .frame(width: 40, height: 40)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                ZStack {
                    Image("Crown")
                        .renderingMode(.original)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 23, height: 23)
                        .shadow(radius: 1)
                }
                .offset(x: 0, y: -25)
                .rotationEffect(.degrees(12))
            }
            
            ForEach(self.friendRiders.indices, id: \.self) { rider in
                Image(friendRiders[rider])
                    .renderingMode(.original)
                    .resizable()
                    .frame(width: 34, height: 34)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                    .zIndex(Double(friendRiders.count + nonFriendRiders.count - rider) )
            }
            
            ForEach(self.nonFriendRiders.indices, id: \.self) { rider in
                Image(nonFriendRiders[rider])
                    .renderingMode(.original)
                    .resizable()
                    .frame(width: 34, height: 34)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                    .zIndex(Double(nonFriendRiders.count - rider))
            }
        }
        Spacer()
    }.padding(.vertical)
    }
 }

Output:-

Screen shot

My Goal:-

Screen shot

Can someone please explain to me how to show images under in HStack, I've tried to implement by above but no results yet.

Any help would be greatly appreciated.

Thanks in advance.

Sham Dhiman
  • 1,348
  • 1
  • 21
  • 59

3 Answers3

2

With zIndex you can do it


enter image description here

Version 1.0.0

struct ImageStackRoundUpr: View {
    
    var friendImages = ["1", "2", "3", "4", "5"]
    
    var body: some View {
        
        HStack(spacing: -10.0) {

            ForEach(friendImages.indices, id: \.self) { index in
                Image(friendImages[index])
                    .resizable()
                    .scaledToFit()
                    .frame(width: 80, height: 80)
                    .background(Color.gray)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.black, lineWidth: 2))
                    .zIndex(Double(friendImages.count - index))
            }

            Spacer()

        }
        .background(Color.green)
  
    }
}

Version 2.0.0

ultimately you would looking for this

enter image description here


import SwiftUI

struct ContentView: View {
    var body: some View {
        
        zIndexHierarchyView()
        
    }
}

struct zIndexHierarchyView: View {

    let imageArray: [String] = ["1", "2", "3", "4", "5"]
    
    var body: some View {
        
        ScrollView(.horizontal, showsIndicators: false) {
            
            HStack(spacing: -30.0) {
                
                ForEach(imageArray.indices, id: \.self) { index in
                    
                    Image(imageArray[index])
                        .resizable()
                        .scaledToFit()
                        .frame(width: 150, height: 150)
                        .background(Color.gray)
                        .clipShape(Circle())
                        .overlay(Circle().strokeBorder(Color.black, lineWidth: 3))
                        .zIndex(Double(imageArray.count + imageArray.count - index))  // <<: Here!
                        .shadow(radius: 10)
                    
                }
                
                ForEach(imageArray.indices, id: \.self) { index in
                    
                    Image(imageArray[index])
                        .resizable()
                        .scaledToFit()
                        .frame(width: 150, height: 150)
                        .background(Color.gray)
                        .clipShape(Circle())
                        .overlay(Circle().stroke(Color.black, lineWidth: 3))
                        .zIndex(Double(imageArray.count - index))                    // <<: Here!
                        .shadow(radius: 10)
                    
                }
                
            }
            .padding(10)
            .background(Color.green)
            .cornerRadius(10)
            
        }
        .shadow(radius: 10)
        .statusBar(hidden: true)
        
    }
}

Version 2.0.1

About update: this update made just per request of OP for solving new issue!


enter image description here

struct ImageStackRoundUpr: View {
    
    var friendRiders = ["1", "2", "3", "4", "5"]
    var nonFriendRiders = ["1", "2", "3", "4", "5"]
    
    var body: some View {
        
        HStack(spacing: -10) {
            
            Image("1")
                .renderingMode(.original)
                .resizable()
                .frame(width: 40, height: 40)
                .background(Color.gray)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.black, lineWidth: 1))
                .zIndex(Double(friendRiders.count + nonFriendRiders.count + 1))
                .overlay(Image("Crown")
                            .renderingMode(.original)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 23, height: 23)
                            .shadow(radius: 1)
                            .offset(x: 0, y: -25)
                            .rotationEffect(.degrees(12)))
            
            ForEach(self.friendRiders.indices, id: \.self) { rider in
                
                Image(friendRiders[rider])
                    .renderingMode(.original)
                    .resizable()
                    .frame(width: 34, height: 34)
                    .background(Color.gray)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.black, lineWidth: 1))
                    .zIndex(Double(friendRiders.count + nonFriendRiders.count - rider))
                
            }
            
            ForEach(self.nonFriendRiders.indices, id: \.self) { rider in
                
                Image(nonFriendRiders[rider])
                    .renderingMode(.original)
                    .resizable()
                    .frame(width: 34, height: 34)
                    .background(Color.gray)
                    .clipShape(Circle())
                    .overlay(Circle().stroke(Color.black, lineWidth: 1))
                    .zIndex(Double(nonFriendRiders.count - rider))
            }
            
            
            Spacer()
            
        }
        .padding(.vertical)

    }
}
ios coder
  • 1
  • 4
  • 31
  • 91
1

Try the following:

struct ContentView: View {
    var friendImages: [Color] = [Color.red, Color.green, Color.blue]
    var body: some View {
        HStack(spacing:-6) {
            Group {
                ForEach(friendImages, id: \.self) { imgeName in
                    imgeName
                        .frame(width: 40, height: 40)
                        .clipShape(Circle())
                        .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                        .zIndex(Double(friendImages.count) - Double(friendImages.firstIndex(of: imgeName) ?? 0))
                }
            }
            Spacer()
        }.padding(.vertical)
    }
}

So the key here is the .zIndex(...) modifier. You can read more about it in the docs: https://developer.apple.com/documentation/swiftui/view/zindex(_:)

Edit:
To answer the updated question: I wouldn't use three different ForEach loops. Instead, I would simply adjust my array:

struct ContentView: View {
    var friendImages: [Color] = [Color.red, Color.green, Color.blue].repeated(count: 3)
    var body: some View {
        HStack(spacing: -6) {
            Group {
                ForEach(friendImages.indices, id: \.self) { i in
                    friendImages[i]
                        .frame(width: 40, height: 40)
                        .clipShape(Circle())
                        .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                        .zIndex(Double(friendImages.count - i))
                }
            }
            Spacer()
        }.padding(.vertical)
    }
}

extension Array {
  init(repeating: [Element], count: Int) {
    self.init([[Element]](repeating: repeating, count: count).flatMap{$0})
  }

  func repeated(count: Int) -> [Element] {
    return [Element](repeating: self, count: count)
  }
}

See this question for reference: Repeating array in Swift

finebel
  • 2,227
  • 1
  • 9
  • 20
1

The possible solution (because all of them in one container) is to use zIndex to make them drawing in reverse order, like

    ForEach(friendImages.indices, id: \.self) { i in
        Image(friendImages[i])
            .resizable()
            .frame(width: 40, height: 40)
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.gray, lineWidth: 1))
            .zIndex(Double(friendImages.count - i))
    }
Asperi
  • 228,894
  • 20
  • 464
  • 690