В моем ContentView
есть кнопка, которая делает простой sheet
подарок моего SettingsView
. Кажется, есть некоторый конфликт с моим @EnvironmentObject var iconSettings: IconNames
в SettingsView
, когда представление представлено модально, где моя функция onReceive
запускается только при первом просмотре загрузки и никогда, когда Picker
используется.
Осматривая ответы, связанные с этим, я смог найти только что-то связанное с CoreData, которое не очень помогло, но я уверен, что другие это испытали, поэтому было бы здорово иметь что-то каноническое и более общее для других. ссылка.
Спасибо!
Button(action: { self.modalDisplayed = true }) {
Assets.gear
}.sheet(isPresented: $modalDisplayed) {
SettingsView(state: self.state, loadCards: self.load)
.environmentObject(IconNames())
}
Затем в моем окне настроек отображается следующее:
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)
}
}
}
}