본문 바로가기
Dev/iOS

[SwiftUI] Casousel 구현

by steady.dev 2021. 10. 29.

1. iOS 14 미만 Casousel 구현

더보기

Carousel 과 현재 page를 표시할 수 있는 Page Controller를 각각 구현해서 사용해야 한다.

 

1. Carousel View 구조체 구현

struct Carousel: UIViewRepresentable {
    func makeCoordinator() -> Coordinator {
        return Carousel.Coordinator(parent1: self)
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
        print("")
    }
    
    
    var width: CGFloat
    @Binding var page: Int
    var height: CGFloat
    
    func makeUIView(context: Context) -> some UIScrollView {
        // ScrollView Content Size...
        
        let total = width * CGFloat(data.count)
        let view = UIScrollView()
        view.isPagingEnabled = true
        
        // 1.0 For Disabling Vertical Scroll...
        view.contentSize = CGSize(width: total, height: 1.0)
        view.bounces = true
        view.showsVerticalScrollIndicator = false
        view.showsHorizontalScrollIndicator = false
        view.delegate = context.coordinator
        
        // Now Going to Embed swiftUI View Into UIView..
        let view1 = UIHostingController(rootView: List(page: self.$page))
        view1.view.frame = CGRect(x: 0, y: 0, width: total, height: self.height)
        
        view1.view.backgroundColor = .clear
        
        view.addSubview(view1.view)
        
        
        return view
    }
    
    class Coordinator: NSObject, UIScrollViewDelegate {
        var parent: Carousel
        init(parent1: Carousel) {
            parent = parent1
        }
        func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            // Using This Fuction For Getting Current Page
            let page = Int(scrollView.contentOffset.x / UIScreen.main.bounds.width)
//            print(page)
            self.parent.page = page
        }
    }
}

2. Page Controller 구현

struct PageControl: UIViewRepresentable {
    @Binding var page: Int
    func makeUIView(context: Context) -> UIPageControl {
        let view = UIPageControl()
        view.currentPageIndicatorTintColor = .black
        view.pageIndicatorTintColor = UIColor.black.withAlphaComponent(0.2)
        view.numberOfPages = data.count
        view.currentPage = self.page
        return view
    }
    
    func updateUIView(_ uiView: UIPageControl, context: Context) {
        // Updating Page Indicator When Ever Page Changes
        DispatchQueue.main.async {
            print(self.page)
            uiView.currentPage = self.page
        }
        
    }
}

 

3. 사용

VStack {
  // Using GeomtryReeader For Getting Remaining Height
  GeometryReader { g in
  	Carousel(width: UIScreen.main.bounds.width, page: self.$page, height: UIScreen.main.bounds.height)
  }

  PageControl(page: self.$page)
  	.padding(.top, 20)
}

 

 

2. iOS 14 이상 Carousel 구현

더보기

기본구현

struct ContentView: View {
    var body: some View {

        TabView {
            Text("Page1").foregroundColor(.white)
            Text("Page2").foregroundColor(.white)
        }
        //.tabViewStyle(PageTabViewStyle.init(indexDisplayMode: .always))
        .tabViewStyle(.page(indexDisplayMode: .always))
        .background(Color.black)
        .edgesIgnoringSafeArea(.all)

    }
}

 

Custom Page Controller 구현

struct ContentView: View {

    init() {
        UIPageControl.appearance().currentPageIndicatorTintColor = .red
        UIPageControl.appearance().pageIndicatorTintColor = UIColor.white.withAlphaComponent(0.8)
    }

    var body: some View {

        TabView {
            Text("page1").foregroundColor(.white)
            Text("page2").foregroundColor(.white)
        }
        //.tabViewStyle(PageTabViewStyle.init(indexDisplayMode: .always))
        .tabViewStyle(.page(indexDisplayMode: .always))
        .background(Color.black)
        .edgesIgnoringSafeArea(.all)

    }
}

댓글