ios - 将 .environmentObject 与呈现为工作表的 View 一起使用会导致 onReceive 不触发/与 @EnvironmentObject 冲突

标签 ios swift swiftui

在我的 ContentView ,我有一个简单的按钮 sheet我的礼物SettingsView .好像和我的@EnvironmentObject var iconSettings: IconNames有些冲突在 SettingsView当 View 以模态方式呈现时,我的 onReceive函数仅在 View 第一次加载时触发,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

关于ios - 将 .environmentObject 与呈现为工作表的 View 一起使用会导致 onReceive 不触发/与 @EnvironmentObject 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60156569/

相关文章:

swiftui - LineChart 在 Xcode 11.1 和 11.2 beta 中不起作用

ios - 按下 TextField 时向上移动 UIView

ios - 我可以为 iOS 应用程序和网站使用一个解析数据库吗? - 使用 swift

ios - 在将新界面推送到界面 Controller 上后,如何关闭由界面 Controller 组成的两个页面中不需要的页面?在 Watchkit 上

swift - 如何修复 "Optimization Opportunities"

ios - 如何从自定义 View 单元格重新加载数据?

ios - SwiftUI 对其 Root View 的一些 View

SwiftUI macOS 命令(菜单栏)和 View

iphone - 从 iOS 中的 App Delegate 调用当前 View Controller 中的方法

ios - 如何分配标签文本属性以显示数组中的字符串?