nachonavarro / Pages

📖 A lightweight, paging view solution for SwiftUI
MIT License
552 stars 52 forks source link

Page index issue #6

Closed furasli closed 4 years ago

furasli commented 4 years ago

When i want to show current index, rightToLeft swipe is not working. If i enter to some text (like Text("Test header"), it's working. Really interesting.

`import Pages

struct WelcomeView: View {

@State var index: Int = 0

var body: some View {
  VStack {
    Text("\(index)")
    Spacer()
    Pages(currentPage: $index) {
         Text("Welcome! This is Page 1")
         Text("This is Page 2")
         Text("...and this is Page 3")
         Circle() // The 4th page is a Circle
    }
  }
}

}`

cargath commented 4 years ago

I've been debugging this for some time now, because i had the same issue when i tried to design a more SwiftUIy API around the version from Apples tutorial (https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit). I think i found the problem, but didn't come up with a satisfying solution yet.

When you store the UIHostingControllers on a level below the one that's holding the @State property, updates off the property trigger them to be reloaded. It doesn't change the currently shown view controller, the index of which it uses to determine the next / previous page. Because it's not part of the array of view controllers anymore, the data source can't compute this index.

I suspect not accessing the @State property prevents SwiftUI from triggering updates when it changes (maybe to safe resources?), which is why it only breaks when you try to actually do something with it.

The reason i haven't come up with a fix yet is, that i'm not sure this is fixable - maybe it's possible to restore the state correctly after reloading all the UIHostingControllers, but maybe we shouldn't be recreating them all the time in the first place? I don't what difference to performance it actually makes, but it seems wasteful.

nachonavarro commented 4 years ago

I've had some time to look at the issue, but if I understood you guys correctly it's working on my end. For example this works and lets me swipe right to left:

import SwiftUI
import Pages

struct HomeView: View {

    @State var index = 0

    var body: some View {
        VStack {
            Text("The current index is: \(self.index)")
            Pages(currentPage: $index) {
                Text("Page 1")
                Text("Page 2")
                Text("Page \(self.index + 1)")
            }
        }
    }
}

struct HomeView_Previews: PreviewProvider {
    static var previews: some View {
        HomeView()
    }
}

Does this solve your problem?