rotation issues (#13)
* animate indicator bar fix rotation issue * requested changes
This commit is contained in:
parent
16ee70ccc9
commit
80a2937f8e
|
@ -38,7 +38,6 @@ private struct PagerSetAppearItem: ViewModifier {
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
content
|
content
|
||||||
.frame(width: pagerSettings.width, height: pagerSettings.height)
|
|
||||||
.overlay(
|
.overlay(
|
||||||
GeometryReader { reader in
|
GeometryReader { reader in
|
||||||
Color.clear
|
Color.clear
|
||||||
|
@ -68,7 +67,6 @@ private struct PagerTabItem<NavTabView: View> : ViewModifier {
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
PagerTabView(navTabView: navTabView) {
|
PagerTabView(navTabView: navTabView) {
|
||||||
content
|
content
|
||||||
.frame(width: pagerSettings.width, height: pagerSettings.height)
|
|
||||||
.overlay(
|
.overlay(
|
||||||
GeometryReader { reader in
|
GeometryReader { reader in
|
||||||
Color.clear
|
Color.clear
|
||||||
|
@ -108,25 +106,26 @@ private struct NavBarModifier: ViewModifier {
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
LazyHStack(spacing: pagerSettings.tabItemSpacing) {
|
HStack(spacing: pagerSettings.tabItemSpacing) {
|
||||||
if itemCount > 0 && pagerSettings.width > 0 {
|
if itemCount > 0 && pagerSettings.width > 0 {
|
||||||
ForEach(0...itemCount-1, id: \.self) { idx in
|
ForEach(0...itemCount-1, id: \.self) { idx in
|
||||||
NavBarItem(id: idx, selection: $indexSelected)
|
NavBarItem(id: idx, selection: $indexSelected)
|
||||||
.frame(width: navBarItemWidth, height: pagerSettings.tabItemHeight, alignment: .center)
|
.frame(height: pagerSettings.tabItemHeight, alignment: .center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(width: pagerSettings.width, height: pagerSettings.tabItemHeight, alignment: .center)
|
.frame(height: pagerSettings.tabItemHeight, alignment: .center)
|
||||||
HStack {
|
HStack {
|
||||||
if let width = navBarItemWidth, width > 0, width <= pagerSettings.width {
|
if let width = navBarItemWidth, width > 0, width <= pagerSettings.width {
|
||||||
let x = -self.pagerSettings.contentOffset / CGFloat(itemCount) + width / 2
|
let x = -self.pagerSettings.contentOffset / CGFloat(itemCount) + width / 2
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.fill(pagerSettings.indicatorBarColor)
|
.fill(pagerSettings.indicatorBarColor)
|
||||||
|
.animation(.default)
|
||||||
.frame(width: width)
|
.frame(width: width)
|
||||||
.position(x: x, y: 0)
|
.position(x: x, y: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(width: pagerSettings.width, height: pagerSettings.indicatorBarHeight)
|
.frame(height: pagerSettings.indicatorBarHeight)
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +194,7 @@ public class PagerSettings: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Public Source Cide
|
/// Public Source Code
|
||||||
///
|
///
|
||||||
|
|
||||||
@available(iOS 14.0, *)
|
@available(iOS 14.0, *)
|
||||||
|
@ -212,7 +211,7 @@ public struct XLPagerView<Content> : View where Content : View {
|
||||||
self.pagerSettings.contentOffset = currentOffset
|
self.pagerSettings.contentOffset = currentOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@State private var itemCount : Int = 0
|
@State private var itemCount : Int = 0
|
||||||
@GestureState private var translation: CGFloat = 0
|
@GestureState private var translation: CGFloat = 0
|
||||||
|
|
||||||
|
@ -229,17 +228,29 @@ public struct XLPagerView<Content> : View where Content : View {
|
||||||
GeometryReader { gproxy in
|
GeometryReader { gproxy in
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
content()
|
content()
|
||||||
|
.frame(width: gproxy.size.width)
|
||||||
}
|
}
|
||||||
.frame(width: pagerSettings.width, height: pagerSettings.height, alignment: .leading)
|
|
||||||
.offset(x: -CGFloat(self.currentIndex) * pagerSettings.width)
|
.offset(x: -CGFloat(self.currentIndex) * pagerSettings.width)
|
||||||
.offset(x: self.translation)
|
.offset(x: self.translation)
|
||||||
.animation(.interactiveSpring(response: 0.5, dampingFraction: 1.00, blendDuration: 0.25), value: currentIndex)
|
.animation(.interactiveSpring(response: 0.5, dampingFraction: 1.00, blendDuration: 0.25), value: currentIndex)
|
||||||
.animation(.interactiveSpring(response: 0.5, dampingFraction: 1.00, blendDuration: 0.25), value: translation)
|
.animation(.interactiveSpring(response: 0.5, dampingFraction: 1.00, blendDuration: 0.25), value: translation)
|
||||||
.gesture(
|
.gesture(
|
||||||
DragGesture().updating(self.$translation) { value, state, _ in
|
DragGesture().updating(self.$translation) { value, state, _ in
|
||||||
state = value.translation.width
|
if (currentIndex == 0 && value.translation.width > 0) {
|
||||||
|
let valueWidth = value.translation.width
|
||||||
|
let normTrans = valueWidth / (gproxy.size.width + 50)
|
||||||
|
let logValue = log(1 + normTrans)
|
||||||
|
state = gproxy.size.width/1.5 * logValue
|
||||||
|
} else if (currentIndex == itemCount - 1 && value.translation.width < 0) {
|
||||||
|
let valueWidth = -value.translation.width
|
||||||
|
let normTrans = valueWidth / (gproxy.size.width + 50)
|
||||||
|
let logValue = log(1 + normTrans)
|
||||||
|
state = -gproxy.size.width / 1.5 * logValue
|
||||||
|
} else {
|
||||||
|
state = value.translation.width
|
||||||
|
}
|
||||||
}.onEnded { value in
|
}.onEnded { value in
|
||||||
let offset = value.predictedEndTranslation.width / pagerSettings.width
|
let offset = value.predictedEndTranslation.width / gproxy.size.width
|
||||||
let newPredictedIndex = (CGFloat(self.currentIndex) - offset).rounded()
|
let newPredictedIndex = (CGFloat(self.currentIndex) - offset).rounded()
|
||||||
let newIndex = min(max(Int(newPredictedIndex), 0), self.itemCount - 1)
|
let newIndex = min(max(Int(newPredictedIndex), 0), self.itemCount - 1)
|
||||||
if abs(self.currentIndex - newIndex) > 1 {
|
if abs(self.currentIndex - newIndex) > 1 {
|
||||||
|
@ -252,7 +263,9 @@ public struct XLPagerView<Content> : View where Content : View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.clipped()
|
.onChange(of: gproxy.frame(in: .local), perform: { geo in
|
||||||
|
pagerSettings.width = geo.width
|
||||||
|
})
|
||||||
.onChange(of: self.currentIndex) { [currentIndex] newIndex in
|
.onChange(of: self.currentIndex) { [currentIndex] newIndex in
|
||||||
self.currentOffset = self.offsetForPageIndex(newIndex)
|
self.currentOffset = self.offsetForPageIndex(newIndex)
|
||||||
if let callback = navContentViews.items.value[currentIndex]?.appearCallback {
|
if let callback = navContentViews.items.value[currentIndex]?.appearCallback {
|
||||||
|
@ -289,6 +302,7 @@ public struct XLPagerView<Content> : View where Content : View {
|
||||||
tabViewDelegate.setSelectedState(state: .selected)
|
tabViewDelegate.setSelectedState(state: .selected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.clipped()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func offsetForPageIndex(_ index: Int) -> CGFloat {
|
private func offsetForPageIndex(_ index: Int) -> CGFloat {
|
||||||
|
|
Loading…
Reference in New Issue