본문 바로가기

모바일 개발/iOS 앱 개발

[Swift] 커스텀 탭(PagerTabStrip) 구현하기

커스텀 탭(PagerTabStrip)은 자주 사용하는 UI이기도 하고 안드로이드에서도 제공하는 기능이기 때문에 당연히 애플에서 제공할 것이라고 생각했는데, 애플에서는 제공하지 않는 기능이네요. 😭

다행히도 많은 개발자들이 이미 구현을 해놔 아래 코드를 통해 손쉽게 tab 을 구현할 수 있었습니다.

 

 

1. tab 생성

 

 

 

struct AppBar : View {
    
    @Binding var index : Int
    @Binding var offset : CGFloat
    var width = UIScreen.main.bounds.width
    
    var body: some View{
        
        VStack(alignment: .leading, content: {
            
            HStack{
                
                Button(action: {
                    
                    self.index = 1
                    self.offset = self.width
                }) {
                    
                    VStack(spacing: 8){
                        
                        HStack(spacing: 12){

                            
                            Text("tap1")
                                .foregroundColor(self.index == 1 ? .black : Color.black.opacity(0.7))
                        }
                        
                        Capsule()
                            .fill(self.index == 1 ? Color.black : Color.clear)
                            .frame(height: 4)
                    }
                }
                
                Button(action: {
                    
                    self.index = 2
                    self.offset = 0
                    
                }) {
                    
                    VStack(spacing: 8){
                        
                        HStack(spacing: 12){
                            
                            Text("tap2")
                                .foregroundColor(self.index == 2 ? .black : Color.black.opacity(0.7))
                        }
                        
                        Capsule()
                            .fill(self.index == 2 ? Color.black : Color.clear)
                            .frame(height: 4)
                    }
                }
                
                Button(action: {
                    
                    self.index = 3
                    self.offset = -self.width
                    
                }) {
                    
                    VStack(spacing: 8){
                        
                        HStack(spacing: 12){
                            
                            Text("tap3")
                                .foregroundColor(self.index == 3 ? .black : Color.black.opacity(0.7))
                        }
                        
                        Capsule()
                            .fill(self.index == 3 ? Color.black : Color.clear)
                            .frame(height: 4)
                    }
                }

            }
        })
        .padding(.top, (UIApplication.shared.windows.first?.safeAreaInsets.top)! + 15)
        .padding(.horizontal)
    }
}

 

2. 탭과 화면 연결

struct Home : View {
    
    @State var index = 1
    @State var offset : CGFloat = UIScreen.main.bounds.width
    var width = UIScreen.main.bounds.width
    
    var body: some View{
        
        VStack(spacing: 0){
            
            AppBar(index: self.$index, offset: self.$offset)
            
            GeometryReader{g in
                
                HStack(spacing: 0){
                    
                    First()
                        .frame(width: g.frame(in : .global).width)
                    
                    Scnd()
                        .frame(width: g.frame(in : .global).width)
                    
                    Third()
                        .frame(width: g.frame(in : .global).width)
                }
                .offset(x: self.offset)
                .highPriorityGesture(DragGesture()
                
                .onEnded({ (value) in
                
                    if value.translation.width > 50{// minimum drag...
                        
                        print("right")
                        self.changeView(left: false)
                    }
                    if -value.translation.width > 50{
                        
                        print("left")
                        self.changeView(left: true)
                    }
                }))
                
            }
        }
        .animation(.default)
        .edgesIgnoringSafeArea(.all)
    }

 

 

참고

https://www.youtube.com/watch?v=KdEqmYpQo6s