이번에는 계산된 pageOffset을 기반으로 스크롤의 진행도를 계산한다.
Home
before
let pageOffset = minX - (size.width * CGFloat(tab.index))
print(pageOffset)
}
계산된 pageOffset를 출력하는 부분에서 이를 진행하면 될 것이다.
after
let pageOffset = minX - (size.width * CGFloat(tab.index))
let pageProgress = pageOffset / size.width
scrollProgress = pageProgress
}
pageOffset을 다시 화면의 너비(사진의 너비)로 나누어 주면 다음과 같은 형태로 변환이 된다.
imageView의 위치값(offset)이 progress로 변환된 모습이다.
대단히 의미 있는 변화는 아니지만 각각의 index와 굉장히 유사한 값들을 보여주는 것을 확인할 수 있다.
또한 이렇게 변환된 값은 곧바로 scrollProgress를 업데이트하는 데 사용되기 때문에
드디어 TabView와 Tab Indicator가 연동돼 움직이기 시작한다.
스크롤 제한하기
Tab View의 동작과 연동이 되기 때문에 맨 앞과 맨 뒤의 경우 Tab View가 튕기는 것도 동일하게 반응한다.
이를 제한해 처음과 끝에서는 Tab Indicator의 불필요한 움직임을 제한해 보도록 한다.
특정한 변수의 최대와 최소를 제한하는 것은 여러 방식이 있지만 min과 max를 사용해 본다.
min()
max()
각자 대상 변수와 기준 값을 전달해 최대와 최소를 제한한다.
Home
before
TabView(selection: $activeTab) {
ForEach(Tab.allCases, id: \.rawValue) { tab in
TabImageView(tab)
.tag(tab)
.offsetX(activeTab == tab) { rect in
let minX = rect.minX
let pageOffset = minX - (size.width * CGFloat(tab.index))
let pageProgress = pageOffset / size.width
scrollProgress = pageProgress
}
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
after
TabView(selection: $activeTab) {
ForEach(Tab.allCases, id: \.rawValue) { tab in
TabImageView(tab)
.tag(tab)
.offsetX(activeTab == tab) { rect in
let minX = rect.minX
let pageOffset = minX - (size.width * CGFloat(tab.index))
let pageProgress = pageOffset / size.width
scrollProgress = max(min(pageProgress, 0), -CGFloat(Tab.allCases.count - 1))
}
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
min()과 max()를 겹쳐 사용해 최솟값은 0으로, 최댓값은 Tab의 최대 index의 음수로 지정한다.
Tab View의 처음과 끝에서는 Tab View의 움직임과는 별개로 Tab Indicator의 상태는 변함이 없는 것을 확인할 수 있다.
'학습 노트 > UIBreaking (2023)' 카테고리의 다른 글
AutoScrolling #06 (0) | 2023.04.07 |
---|---|
AutoScrolling #05 (0) | 2023.04.04 |
AutoScrolling #03 (0) | 2023.03.23 |
AutoScrolling #02 (0) | 2023.03.22 |
AutoScrolling #01 (0) | 2023.03.16 |