ios - 将 .environmentObject 与呈现为工作表的视图一起使用会导致 onReceive 不触发/与 @EnvironmentObject 冲突
问题描述
在我的ContentView
中,我有一个按钮,可以简单sheet
地呈现我的SettingsView
. 当视图以模态方式呈现时,我@EnvironmentObject var iconSettings: IconNames
的 in似乎存在一些冲突,其中我的函数仅在视图第一次加载时触发,而在使用时永远不会触发。SettingsView
onReceive
Picker
环顾四周寻找与此相关的答案,我只能找到与 CoreData 相关的东西,这并没有真正的帮助,但我相信其他人已经经历过这个,所以有一些规范和更通用的东西供其他人参考会很棒。
谢谢!
Button(action: { self.modalDisplayed = true }) {
Assets.gear
}.sheet(isPresented: $modalDisplayed) {
SettingsView(state: self.state, loadCards: self.load)
.environmentObject(IconNames())
}
然后在我的 SettingsView 中,我有以下内容:
struct SettingsView: View {
@ObservedObject var state: AppState
@EnvironmentObject var iconSettings: IconNames
let loadCards: () -> Void
var body: some View {
VStack {
Picker("", selection: $iconSettings.currentIndex) {
ForEach(Publication.allCases, id: \.pubId) {
Text($0.pubName).tag($0.pubId)
}
}
.pickerStyle(SegmentedPickerStyle())
.padding(20)
Spacer()
}
.onReceive([self.iconSettings.currentIndex].publisher.first()) { value in
print(value) // only hits on first load, never on tap
print("")
let index = self.iconSettings.iconNames.firstIndex(of: UIApplication.shared.alternateIconName) ?? 0
if index != value { UIApplication.shared.setAlternateIconName(self.iconSettings.iconNames[value]) { error in
if let error = error {
print(error.localizedDescription)
} else {
print("Success!")
}
}
}
}
}
}
最后,我的 IconNames 类:
class IconNames: ObservableObject {
var iconNames: [String?] = [nil]
@Published var currentIndex = 0
init() {
getAlternateIconNames()
if let currentIcon = UIApplication.shared.alternateIconName {
self.currentIndex = iconNames.firstIndex(of: currentIcon) ?? 0
}
}
func getAlternateIconNames() {
if let icons = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as? [String: Any],
let alternateIcons = icons["CFBundleAlternateIcons"] as? [String: Any]
{
for (_, value) in alternateIcons{
guard let iconList = value as? Dictionary<String,Any> else{return}
guard let iconFiles = iconList["CFBundleIconFiles"] as? [String]
else{return}
guard let icon = iconFiles.first else{return}
iconNames.append(icon)
}
}
}
}
解决方案
好吧,由于提供的代码快照不能通过复制粘贴来测试,所以只能通过代码阅读,尝试而不是
.onReceive([self.iconSettings.currentIndex].publisher.first()) { value in
用这个
.onReceive(self.iconSettings.$currentIndex) { value in
推荐阅读
- swift - 是否有一种通用的方法来处理异步和快速抛出的组合
- domain-driven-design - 如何处理resolvejs中聚合根之间的关系
- java - JSF 状态持有者保护程序内存泄漏
- java - 错误:无法在 AutoCompleteTextView 中推断 ArrayAdapter<> 的类型参数
- redis - Redis BITCOUNT 行为
- r - 使用逗号分隔的字符串查找数据集变量中的所有项目
- javascript - 另一个 Promise 的 .then() 内的 for-each 循环内的 Promise 链
- java - 多种类型的杰克逊反序列化接口
- r - R shapefile 找不到并加载问题
- android - getExternalFilesDirs 不返回 SD 卡,仅返回内部/内置存储