포스트

TourApp (3)

DetailView 꾸미기 & PageView 꾸미기

Page view 꾸미기

이전에 회고를 하던도중 Tabview를 통해 UIKit의 TabBarViewController로 쓸수있고 이미지를 페이징하면서 넘기는 방식으로도 사용이 가능하다고 하여 그걸 적용해보기로했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@State private var currentPage: Int = 0

TabView(selection: $currentPage.animation()) {
                ForEach(lists.indices, id: \.self) { index in
                        VStack {
                            AsyncImage(url: URL(string: lists[index].imageURL)) { image in
                                image
                                    .resizable()
                                    .frame(maxWidth: 150, maxHeight: 150)
                            } placeholder: {
                                Image(systemName: "photo")
                            }
                            Link(destination: URL(string: lists[index].shopURL)!) { Text(lists[index].shopTitle)
                                    .fontWeight(.bold)
                                    .foregroundStyle(.blue)
                        }
                    }
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))

이렇게 해서 적용을 했는데 아이러니 하게도 indicator가 아래에있거나 뭔가 원하는 위치에 되지않는 문제가 발생했다.

그래서 고민을 하다가 medium의 글을 참고하여 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    ForEach(0..<lists.count, id: \.self) { index in
                        Circle()
                            .frame(width: index == currentPage ? 12 : 8, height: index == currentPage ? 16 : 10)
                            .foregroundStyle(.blue.opacity(index == currentPage ? 1 : 0.5))
                    }
                }
                .padding(.horizontal)
                .scrollTargetLayout()
            }
            .background(.clear, in: RoundedRectangle(cornerRadius: 30))
            .frame(width: 60)
            .scrollTargetBehavior(.viewAligned)
            .scrollPosition(id: Binding($currentPage), anchor: .center)
            .allowsTightening(false)

뭐 크게 설명할 내용은 없어보이지만 modifier 몇개만 좀 짚어보고 넘어간다.

📘 SwiftUI의 ScrollView 모디파이어 설명: .scrollTargetBehavior, .scrollPosition, .allowsTightening

SwiftUI에서 ScrollView에 사용할 수 있는 모디파이어들은 스크롤 동작과 위치 조정에 중요한 역할을 합니다. 이 중 .scrollTargetBehavior(), .scrollPosition(), .allowsTightening()에 대해 설명하겠습니다.


1️⃣ .scrollTargetBehavior(.viewAligned)
  • scrollTargetBehavior는 스크롤 동작이 어떻게 처리되는지를 정의하는 모디파이어다.
  • .viewAligned 옵션은 스크롤이 뷰의 경계에 맞춰 정렬되도록 설정한다.
  • 가로 스크롤(.horizontal)에서 주로 사용되며, 탭 간의 스크롤 정렬을 부드럽게 만들어 준다.
  • 스크롤 시 뷰가 정확하게 화면에 나타나도록 자동으로 조정하여, 부드러운 스크롤 경험을 제공한다.

2️⃣ .scrollPosition(id: Binding<Int>, anchor: .center)
  • scrollPosition은 스크롤 위치를 제어하는 모디파이어다.
  • id 파라미터는 바인딩된 값으로, 현재 스크롤 위치를 나타낸다.
  • anchor는 스크롤 위치를 맞출 기준점으로, 주로 .center, .leading, .trailing을 사용한다.
  • 현재 스크롤 위치를 업데이트하고, 선택된 뷰가 특정 위치(예: 화면의 중앙)에 오도록 한다.
  • 페이지 뷰나 탭 뷰와 같이, 현재 페이지가 중앙에 맞추어져야 하는 경우에 주로 사용된다.

3️⃣ .allowsTightening(false)
  • allowsTightening은 텍스트의 줄 간격 압축 여부를 제어하는 모디파이어다.
  • false로 설정하면, 텍스트가 줄어들지 않고 원래의 간격을 유지한다.
  • 기본값은 true이며, 텍스트가 제한된 공간 내에서 줄어들 수 있도록 허용한다.
  • 긴 텍스트가 잘리는 것을 방지하고, 줄 간격이 일관되도록 보장한다.

📝 요약
모디파이어설명
.scrollTargetBehavior(.viewAligned)스크롤이 뷰의 경계에 맞춰 정렬되도록 설정
.scrollPosition(id: Binding, anchor: .center)스크롤 위치를 특정 기준점(anchor)에 맞춰 제어
.allowsTightening(false)텍스트의 줄 간격이 줄어들지 않도록 설정

이 모디파이어들은 ScrollView의 스크롤 동작과 레이아웃을 세밀하게 조정하는 데 유용하다.

Detail view 꾸미기

Scrollview 적용시 frame 을 설정해줘야한다. 그래서 귀찮아서 scrollview를 사용하려다 포기했지만, frame으로 각 사이즈를 주긴했다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.