web-dev-qa-db-fra.com

Déroulez pour actualiser les données dans SwiftUI

j'ai utilisé une simple liste de données en utilisant List. Je voudrais ajouter un menu déroulant pour actualiser la fonctionnalité, mais je ne suis pas sûr de la meilleure approche possible.

Dérouler pour actualiser la vue ne sera visible que lorsque l'utilisateur essaiera de dérouler à partir du tout premier index comme nous l'avons fait dans UITableView avec UIRefreshControl dans UIKit

Voici un code simple pour répertorier les données dans SwiftUI.

struct CategoryHome: View {
    var categories: [String: [Landmark]] {
        .init(
            grouping: landmarkData,
            by: { $0.category.rawValue }
        )
    }

    var body: some View {
        NavigationView {
            List {
                ForEach(categories.keys.sorted().identified(by: \.self)) { key in
                    Text(key)
                }
            }
            .navigationBarTitle(Text("Featured"))
        }
    }
}
18
PinkeshGjr

J'avais besoin de la même chose pour une application avec laquelle je joue, et il semble que l'API SwiftUI n'inclue pas de capacité de contrôle de rafraîchissement pour ScrollViews pour le moment.

Au fil du temps, l'API développera et rectifiera ce genre de situations, mais le repli général des fonctionnalités manquantes dans SwiftUI implémentera toujours une structure qui implémente UIViewRepresentable. Voici un rapide et sale pour UIScrollView avec un contrôle de rafraîchissement.

struct LegacyScrollView : UIViewRepresentable {
    // any data state, if needed

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UIScrollView {
        let control = UIScrollView()
        control.refreshControl = UIRefreshControl()
        control.refreshControl?.addTarget(context.coordinator, action:
            #selector(Coordinator.handleRefreshControl),
                                          for: .valueChanged)

        // Simply to give some content to see in the app
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 30))
        label.text = "Scroll View Content"
        control.addSubview(label)

        return control
    }


    func updateUIView(_ uiView: UIScrollView, context: Context) {
        // code to update scroll view from view state, if needed
    }

    class Coordinator: NSObject {
        var control: LegacyScrollView

        init(_ control: LegacyScrollView) {
            self.control = control
        }

        @objc func handleRefreshControl(sender: UIRefreshControl) {
            // handle the refresh event

            sender.endRefreshing()
        }
    }
}

Mais bien sûr, vous ne pouvez pas utiliser de composants SwiftUI dans votre vue de défilement sans les envelopper dans un UIHostingController et les déposer dans makeUIView, plutôt que de les mettre dans une LegacyScrollView() { // views here }.

17
Evan Deaubl

Voici une implémentation qui introspecte la hiérarchie des vues et ajoute un UIRefreshControl approprié à la vue de table d'une liste SwiftUI: https://github.com/timbersoftware/SwiftUIRefresh

La majeure partie de la logique d'introspection peut être trouvée ici: https://github.com/timbersoftware/SwiftUIRefresh/blob/15d9deed3fec66e2c0f6fd1fd4fe966142a891db/Sources/PullToRefresh.Swift#L39-L7

9
ldiqual

Salut consultez cette bibliothèque que j'ai faite: https://github.com/AppPear/SwiftUI-PullToRefresh

Vous pouvez l'implémenter par une ligne de code:

struct CategoryHome: View {
    var categories: [String: [Landmark]] {
        .init(
            grouping: landmarkData,
            by: { $0.category.rawValue }
        )
    }

    var body: some View {
        RefreshableNavigationView(title: "Featured", action:{
           // your refresh action
        }){
                ForEach(categories.keys.sorted().identified(by: \.self)) { key in
                    Text(key)
                    Divider() // !!! this is important to add cell separation
                }
            }
        }
    }
}
2
Samu Andras

La swiftui-introspects n'est pas encore prise en charge sur masOS, donc si vous allez créer une interface utilisateur qui fonctionne à la fois pour iOS et macOS, pensez à la bibliothèque Samu Andras.

J'ai fourré son code, ajouté quelques améliorations et ajouté la possibilité d'utiliser sans NavigationView

Voici l exemple de code.

RefreshableList(showRefreshView: $showRefreshView, action:{
                           // Your refresh action
                            // Remember to set the showRefreshView to false
                            self.showRefreshView = false

                        }){
                            ForEach(self.numbers, id: \.self){ number in
                                VStack(alignment: .leading){
                                    Text("\(number)")
                                    Divider()
                                }
                            }
                        }

Pour plus de détails, vous pouvez visiter le lien ci-dessous. https://github.com/phuhuynh2411/SwiftUI-PullToRefresh

0
Phu HUYNH