Posts

Post not yet marked as solved
0 Replies
932 Views
Hello all! In my project, I have created a swipeable carousel view that changes a published property (currentHoleIdx) in my ViewModel that I use to programmatically change a TabView. I want the TabView to animate when the index changes, and it does, but only with the deprecated .animated(.easeInOut). I have tried .animation(.easeInOut, value:model.currentHoleIdx) and also tried withAnimation when I change the currentHoleIdx property. I will do my best to post the code to show what I have done. Thanks in advance for any help! TabView with animation  VStack {       ZStack(alignment: .top) {         // Mini Scorecard         MiniScorecard(scorecard:model.scorecards[model.currentScorecardIdx!], teams: model.scorecards[model.currentScorecardIdx!].teams)           .coordinateSpace(name: "mini") //          .opacity(showScore ? 1 : 0)           .background(Color("card"))           .background(             GeometryReader { geo in               Color.clear.onAppear {                 showScoreOffset = geo.size.height                 // print(geo.size.height)               }             }           )                                       // Scorecard TabView         TabView(selection: $model.currentHoleIdx,             content: {               ForEach(0..<model.scorecards[model.currentScorecardIdx!].holes.count) {idx in                 let scorecard = model.scorecards[model.currentScorecardIdx!]                                   if scorecard.formatType == "individual" {                                       if scorecard.gameID == "Standard" {                     IndivStandardScoreScrollview(idx:idx)                       .tag(idx)                       .animation(.easeInOut, value: model.currentHoleIdx) // // does not work does not work with idx or model.currentHoleIdx                                           }                 } else {                                       if scorecard.gameID == "Standard" {                     TeamStandardScoreScrollview(holeIdx:idx)                       .tag(idx)                       .animation(.easeInOut, value: idx) // does not work does not work with idx or model.currentHoleIdx                                           }                 }               }             Color.clear               .tag(model.scorecards[model.currentScorecardIdx!].holes.count)             }).tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))           .background(Color("card"))           .offset(y:showScore ? showScoreOffset : 0)           .animation(.easeInOut, value: showScore)           .animation(.easeInOut, value: scorecardOffset) //          .animation(.easeInOut, value: model.currentHoleIdx) // does not work       }.frame(width:UIScreen.main.bounds.width - 30)     }     .offset(y: scorecardOffset)     .offset(y: model.currentHoleIdx < model.scorecards[model.currentScorecardIdx!].holes.count ? 0 : scorecardHeight)     .padding(.top)     .padding(.horizontal, 15)     .animation(.easeInOut, value: scorecardOffset) .animation(.easeInOut, value: model.currentHoleIdx) // does not work!!! //    .animation(.easeInOut) // Only thing that works! when model.currentHoleIdx changes from drag gesture     .overlay(       GeometryReader { geo in         Color.clear.onAppear {           scorecardHeight = geo.size.height         }       }     ) Swipeable carousel drag gesture - withAnimation when interacting with model.currentHoleIdx return HStack(alignment: .center, spacing: spacing) {       items     }     .offset(x: CGFloat(calcOffset), y: 0)     .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .named("canvas")).updating($screenDrag) { dragValue, gestureState, transaction in //      self.model.screenDrag = Float(currentState.translation.width)               // gestureState == screenDrag       gestureState = dragValue.translation             }.onEnded { value in       // screenDrag = 0 - Don't need this, bc GestureState automatically resets back to initial value               // Swipe to next hole       if (value.translation.width < -15) && self.model.currentHoleIdx < Int(numberOfItems) - 1 {                   // calculate currentholeidx based on swipe width and cardwidth         let calculatedHoleIdx = self.model.currentHoleIdx - Int(floor(value.translation.width/(cardWidth + spacing + 10)))                   withAnimation { // withAnimation Here           self.model.currentHoleIdx = calculatedHoleIdx > Int(numberOfItems - 1) ? Int(numberOfItems - 1) : calculatedHoleIdx         }         let impactMed = UIImpactFeedbackGenerator(style: .medium)         impactMed.impactOccurred()       }               // Swipe to previous hole       if (value.translation.width > 15) && self.model.currentHoleIdx > 0 {                   let calculatedHoleIdx = self.model.currentHoleIdx - Int(ceil((value.translation.width/(cardWidth + spacing + 10))))                   withAnimation { // withAnimation Here           self.model.currentHoleIdx = calculatedHoleIdx < 0 ? 0 : calculatedHoleIdx         }                   self.model.currentHoleIdx = calculatedHoleIdx < 0 ? 0 : calculatedHoleIdx                   let impactMed = UIImpactFeedbackGenerator(style: .medium)         impactMed.impactOccurred()       }         I feel like i've tried every possible iteration of .animation and withAnimation. The only one that works is using the deprecated .animation() modifier. Hope to hear from someone soon. thanks again!
Posted Last updated
.