仅在冷启动或设置更改时重新加载表数据
Posted
技术标签:
【中文标题】仅在冷启动或设置更改时重新加载表数据【英文标题】:Reload table data only if cold launch or settings change 【发布时间】:2022-01-21 19:02:25 【问题描述】:我有一个简单的两个选项卡式应用程序,我正在尝试管理 List
何时或是否从网络重新加载数据。
我希望应用仅在以下情况下重新加载数据:
首次冷启动(关闭状态启动); 从.background
到.active
状态;或
切换SettingsView()
中的设置
我不希望 List
在不切换选项或一般只切换标签的情况下转到 SettingsView()
时重新加载。
// tab view
struct Tabs: View
var body: some View
TabView
ViewOne().tabItem Label("Settings", systemImage: "gear")
ViewTwo().tabItem Label("List", systemImage: "bag")
// ViewOne
struct ViewOne: View
var body: some View
Text("View one: Settings")
// toggles and options here
.onChange(of: option) value in
// do other things here
UserDefaults.standard.set(true, forKey: "reloadList")
// ViewTwo
struct ViewTwo: View
var body: some View
List(arrayItems) item in
.onAppear
if( UserDefaults.standard.bool(forKey: "reloadList") )
reloadData()
UserDefaults.standard.removeObject(forKey: "reloadList")
以上在运行应用程序时有效,我切换设置 - UserDefaults
触发 reloadData()
函数。这也解决了我切换标签(无需设置更改)和不重新加载数据的困境。
但是,由于该表在启动时(冷态或背景)无法获取数据,因此我现在用糟糕的 UX 将自己击中了脚。
我尝试将另一个UserDefaults.standard.set(true, "coldLaunch")
添加到Tabs
视图,然后将reloadList
设置为true
,但直到切换标签然后再返回时才会触发。
我也尝试过从@Environment(\.scenePhase) var scenePhase
设置或触发reloadData()
,但这会在每次启动时触发onAppear
。
也许我没有直接思考,但我试图找出正确的流程效果但不能!
【问题讨论】:
【参考方案1】:我最终尽可能地解决了这个问题,并认为我会在这里为其他可能想在他们的应用中找到解决方法的用户提供它。
在 TabView 中:
struct Tabs: View
@Environment(\.scenePhase) private var scenePhase
var body: some View
TabView
ViewOne().tabItem Label("Settings", systemImage: "gear")
ViewTwo().tabItem Label("List", systemImage: "bag")
// -- when the view is active reload the table
.onChange(of: scenePhase) phase in
if( phase == .active )
reloadData()
然后在另一个要重新加载的视图上添加.onAppear
代码:
.onAppear
if( UserDefaults.standard.bool(forKey: "reloadList") )
reloadData()
UserDefaults.standard.removeObject(forKey: "reloadList")
其中UserDefaults.standard.bool(forKey: "reloadList")
设置为true
从另一个视图的更改。
有一些问题基于应用何时变为inactive
,但由于ios的结构方式,没有任何方法可以隔离inactive
而不访问active / background
状态。
【讨论】:
【参考方案2】:1. cold booting first time (closed state to launch); 2. going from .background to .active state; or 3. toggling a setting in the SettingsView()
对于冷启动:
您可以尝试使用这个https://developer.apple.com/documentation/uikit/uiapplication/1622944-willenterforegroundnotification,或者甚至可能只是将reload()
放在viewDidLoad()
中,因为这是在应用程序第一次启动时调用的。
NotificationCenter.default.addObserver(self, selector:#selector(appToForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
@objc func appToForeground(_ notification: Notification)
print("appToForeground ")
为了在 SettingsView() 中切换设置,我也在使用通知中心。类似的东西
在您的第一个标签的viewDidLoad()
中,您设置了一个观察者
NotificationCenter.default.addObserver(self,
selector: #selector(self.refreshTable),
name: NSNotification.Name(rawValue: "newDataNotif"),
object: nil)
@objc func refreshTable()
reloadData()
self.tableView.reloadData()
然后在您的第二个选项卡上,当您的设置发生更改并且您想在第一个选项卡中重新加载表格时,这就是您所做的。
例如:
user.setting.changed = true
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "newDataNotif"), object: nil)
一旦您的设置发生更改,此通知将发布,然后您放置在第一个选项卡中的observer
将接收通知,然后它会调用@objc func refreshTable()
然后你的表就会刷新。
【讨论】:
以上是关于仅在冷启动或设置更改时重新加载表数据的主要内容,如果未能解决你的问题,请参考以下文章