티스토리 뷰

iOS/SwiftUI

[SwiftUI] Carousel Card View

HarryJeonn 2022. 8. 1. 06:21

Why ?


스와이프하면 다음 카드로 이동하는 UI를 그리고 싶어서 Horizontal ScrollView를 사용했다가 스와이프하면 자동으로 중심을 맞춰주는 뷰를 구현하고 싶었다.

How ?


GeometryReader를 활용했다.

GeometryReader { proxy in
    
		// 스크롤하면 움직일 x축의 값
    let xOffsetToShift = cardWidth + spacing
    
    HStack(spacing: 10) {
        ForEach(Array(viewModel.places.enumerated()), id: \\.0) { idx, place in
            viewModel.createPlaceCard(place: place, index: idx)
        }
    }
    .padding(.leading, 22)
		// xOffsetToShift에 index를 곱해서 offset의 값을 바꿔준다.
    .offset(x: offset - (CGFloat(viewModel.cardCurrentIndex) * xOffsetToShift))
    .gesture(
        DragGesture()
            .updating($offset, body: { value, out, _ in
                out = value.translation.width
            })
						// 어느정도 스크롤을 해야 다음 카드로 넘어갈지 계산하는 부분
            .onEnded({ value in
                let offsetX = value.translation.width
                let progress = -offsetX / (proxy.size.width / 2)
                let roundIndex = progress.rounded()
                
                viewModel.cardCurrentIndex = max(min(viewModel.cardCurrentIndex + Int(roundIndex), viewModel.places.count - 1), 0)
                
                viewModel.slideCard(index)
            })
            .onChanged({ value in
                let offsetX = value.translation.width
                let progress = -offsetX / (proxy.size.width / 2)
                let roundIndex = progress.rounded()
                
                index = max(min(viewModel.cardCurrentIndex + Int(roundIndex), viewModel.places.count - 1), 0)
            })
    )
}
.frame(height: UIScreen.main.bounds.height * 0.13)
.animation(.easeInOut, value: offset == 0)

전체 코드 중 내가 생각하는 핵심 코드부분이다.

카드의 width와 spacing을 더하여 한번 스와이프하면 움직일 x 값을 구했다.

그리고 index와 곱하여 다음 카드에 맞게 계속 움직일 수 있도록 구현했다.

🤔


처음에는 남의 코드를 가져다 쓰려고 하다보니 offset값 계산하는데 애를먹었다.

남의 코드를 보고 그냥 쓰지말고 어떻게 동작하는지 이해하고 직접 계산해보니 조금 수월했다.

역시 무지성으로 가져다가 쓰면 결국 고생하는건 나다.

이해하고 사용하자!

'iOS > SwiftUI' 카테고리의 다른 글

[SwiftUI] TabView  (0) 2022.08.10
[SwiftUI] 코드로 네비게이션 실행하기  (0) 2022.07.20
[SwiftUI] @ObservedObject, @StateObject  (0) 2022.07.07
[SwiftUI] 애플 로그인  (0) 2022.06.15
[SwiftUI] 카카오 로그인  (0) 2022.06.15
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함