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"))
}
}
}
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 ScrollView
s 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 }
.
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
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
}
}
}
}
}
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