본문 바로가기

개발관련

SwiftUI DropDownSelector 컴포넌트 만드는 법

728x90
반응형

2025.01.31 - [개발관련] - Supabase로 Next.js 호스팅하는 방법

 

Supabase로 Next.js 호스팅하는 방법

✅ Supabase를 활용한 Next.js 호스팅 방법Vercel + Supabase (추천 ✅)Next.js의 기본 호스팅 플랫폼인 Vercel을 사용Supabase를 백엔드(Database + Auth + Storage)로 연결가장 안정적이고 쉬운 방법Supabase Storage + Edge F

woowonwoo.tistory.com

 

SwiftUI로 디자인시스템 만드는 법 온라인 강의

 

SwiftUI로 하는 디자인시스템 구현 : SwiftUI로 세상 모든 UI 만드는 법: 완전판 강의 | 무색무취의고

무색무취의고수 | , “앱 개발, 매번 새로 짜는 코드에 지치셨나요?”🤔한 번 만들어 끝나는 게 아니라, 다음 프로젝트에서도 쓸 수 있는 완벽히 재사용 가능한 디자인 시스템을 만들어 봅시다.2

www.inflearn.com

 

 

 

 

 

struct DropDownSelector: View {
  @State private var selectedOption: String = "Option 1"
  @State private var isExpanded: Bool = false
  let options = ["Option 1", "Option 2", "Option 3"]
  
  var body: some View {
    // 셀렉트 박스 영역
    Button(action: {
      withAnimation {
        isExpanded.toggle()
      }
    }) {
      HStack {
        Text(selectedOption)
          .foregroundColor(.primary)
        Spacer()
        Image(systemName: isExpanded ? "chevron.up" : "chevron.down")
          .foregroundColor(.gray)
      }
      .padding()
      .background(Color.gray.opacity(0.2))
      .cornerRadius(8)
    }
    .overlay {
      // 버튼과 같은 위치에 놓되, drop-down 리스트는 오프셋을 줘서 아래에 나타나도록 함.
      if isExpanded {
        VStack(alignment: .leading, spacing: 0) {
          ForEach(options, id: \.self) { option in
            Button(action: {
              selectedOption = option
              withAnimation {
                isExpanded = false
              }
            }) {
              Text(option)
                .padding()
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(Color.white)
                
            }
            .foregroundColor(.primary)
            
            if option != options.last {
              Divider()
            }
          }
        }
        .cornerRadius(8)
        .shadow(radius: 5)
        // 버튼의 아래쪽에 나타나도록 오프셋 적용 (버튼 높이만큼)
        .offset(y: 100)
        // 부드러운 애니메이션 효과
        .transition(.opacity)
        
      }
    }
    .zIndex(.infinity)
  }
}
728x90
반응형