Autumn Sale50% offCOMPOT
Avatars & User ProfilesPro ComponentiOS 16.0+Xcode 15+

Avatar Stack

Overlapping horizontal stack of user avatars with "+X more" counter for teams and social apps.

SwiftUI Implementation

Pure Vanilla Swift • No Dependencies
avatarStack.swift
import SwiftUI

struct UseAvatarStack: View {
    
    let userCount: Int = 21
    
    var body: some View {
        HStack(alignment: .center, spacing: 8) {
            AvatarStack()
            HStack(alignment: .center, spacing: 0) {
                Image(systemName: "plus")
                    .font(.footnote)
                Text("^[\\(userCount) More Happy \\("User")](inflect: true)")
            }
            .font(.body)
            .fontWeight(.semibold)
            .foregroundStyle(.secondary)
            .frame(maxWidth: .infinity, alignment: .leading)
        }
        .padding()
        .frame(maxWidth: .infinity, alignment: .leading)
    }
    
}

#Preview {
    UseAvatarStack()
}


struct AvatarStack: View {
    
    let avatarWidth: CGFloat = 32
    let offset: CGFloat = 20
    let numberOfAvatars = 5
    
    var body: some View {
        // For person avatar images I'm using free images available on https://unsplash.com/
        // Download sample avatar images here:
        // person1: https://drive.google.com/file/d/1mED11zHmbmC-i6CMusf2zHPf2k1LW9LE/view?usp=sharing
        // person2: https://drive.google.com/file/d/1hdPTQV11tEv0_nyTccNCpRnR_Em_j6PS/view?usp=sharing
        // person3: https://drive.google.com/file/d/1W88wgXYd2tuh3osd_vn2aF2hdymIdLv4/view?usp=sharing
        // person4: https://drive.google.com/file/d/1LC548ldgOEN6wxC0h4chMGphQR13okMj/view?usp=sharing
        // person5: https://drive.google.com/file/d/15PQ3FS8nSDRMy2PUU6GyZ8mIn8bME-1D/view?usp=sharing
        
        ZStack {
            ForEach(0..<numberOfAvatars, id: \\.self) { index in
                AvatarSmallBasic(image: "person\\(index + 1)")
//                    .offset(x: CGFloat(index) * offset, y: 0)
                    .offset(x: CGFloat(index - 1) * offset, y: 0)
                    .zIndex(Double(numberOfAvatars - (index - 1)))
            }
        }
        .offset(x: CGFloat(-offset))
        .frame(width: avatarWidth + CGFloat(numberOfAvatars - 1) * offset, height: avatarWidth)
//        .frame(width: CGFloat(avatarWidth + CGFloat(numberOfAvatars - 1) * offset))
        
    }
    
}

#Preview {
    AvatarStack()
}


struct AvatarSmallBasic: View {
    
    let image: String
    let avatarWidth: CGFloat = 32
    
    var body: some View {
        Image(image)
            .resizable()
            .scaledToFit()
            .frame(width: avatarWidth)
            .clipShape(Circle())
            .overlay(Circle().stroke(.gray.opacity(0.3), lineWidth: 1.2))
    }
}

#Preview {
    AvatarSmallBasic(image: "person")
}

Ready to copy and paste directly into any Xcode project running iOS 16.0+.

Recommended Use Cases

  • First-run onboarding flows and feature introductions
  • Dashboard overviews, stats tracking, and metric highlights

Component Details

iOS Compatibility
iOS 16.0+
Xcode Version
Xcode 15+
Platform
iOS
License Tier
Pro
Themes & Contexts
dashboardonboardingaccount
C

Compot for iOS

Native SwiftUI playground app

Preview all 130+ components interactively on your device and copy code straight to Xcode with 1 tap.

Get Compot on the App Store