Как распределять переменные между представлениями и вложенными представлениями в SwiftUI

#swiftui

Вопрос:

У меня есть средство выбора даты, когда значение выбора даты меняется, я хотел бы сохранить его в строковом массиве под названием filterSelections, как мне это сделать? Заранее спасибо.

 import SwiftUI
public var filterSelections: [String: Any]?

func setFilterSelections(name: String, selectedValue: Any) {
    filterSelections[name] = selectedValue
}


struct myMainSwiftUIView: View{

    var body: some View {
        ScrollView {
            VStack{
                mySub1View()
            }
        }
    }
}


struct mySub1View: View {
@State public var fromDate: Date = Calendar.current.date(byAdding: DateComponents(year: -40), to: Date()) ?? Date()

    var body: some View {
        HStack(spacing:10) {
            VStack(alignment:.leading, spacing:20) {
            DatePicker(selection: $fromDate, displayedComponents: .date) {
                Text("From")
                    .font(.body)
                    .fixedSize()
            }
                }
            }
        }
    }
    

}
 

Комментарии:

1. Ваш вопрос мне на самом деле не совсем ясен. Как это Date соотносится с тем String ?

2. Значение средства выбора даты будет частью выбора фильтра. Вот так [«FromDate»: 2020/01/31 ] Моя беда, это не строка, это Любая. Я исправил это.

3. Почему фильтр является словарем типа [String:Any] -будет ли несколько записей?

4. Может быть, но, честно говоря, здесь недостаточно кода, чтобы я мог понять, что на самом деле должно происходить. Но, в общем случае, если вы разделяете состояние между представлениями, вы будете использовать ObservableObject (либо передавая его напрямую, либо через объект среды). [Строка:Any] все еще беспокоит меня-почему это Any -вы не знаете, что фильтруется? Кроме того, использование ! принудительного разворачивания почти всегда является плохой идеей, так как это приведет к сбою вашей программы, если переменная равна нулю. Типы в Swift обычно пишутся с заглавной буквы.

5. @Michelle: Если у вас возникли проблемы с .onChange или iOS 14.0 , то используйте didSet при выборе для той же работы, должен ли я дать вам пример кода?

Ответ №1:

Мне трудно понять, в каком приложении будут храниться все изменения в средстве выбора даты, поскольку не было бы никакого способа отменить их (и в предустановленной iOS 14 я думаю, что колесо сделало бы этот список особенно сумасшедшим, когда все меняется).

Я подозреваю, что вы, вероятно, хотите, чтобы дата вместе с некоторыми другими фильтрами была добавлена вместе. И вы указали, что хотите разделить это состояние между представлениями и подвидами, что я попытался учесть. Я также использовал формат даты, который вы просили.

Я не включил [String:Any] , как сказано в вашем вопросе, «массив», а не словарь.

Здесь много догадок, так как не совсем ясно, какова ваша цель, но, надеюсь, это даст вам некоторые идеи о том, как делиться состоянием.

 
class FilterViewModel : ObservableObject {
    @Published var dateFilter : Date = Calendar.current.date(byAdding: DateComponents(year: -40), to: Date()) ?? Date()
    @Published var myOtherFilter = "Filter1"
    
    static var formatter = DateFormatter()
    
    var allFilters : [String] {
        Self.formatter.dateFormat = "yyyy/MM/dd"
        return [myOtherFilter, Self.formatter.string(from: dateFilter)]
    }
}

struct ContentView: View{
    @StateObject private var filterModel = FilterViewModel()
    
    var body: some View {
        ScrollView {
            VStack{
                MySub1View(filterModel: filterModel)
            }
            ForEach(filterModel.allFilters, id: .self) { filter in
                Text(filter)
            }
        }
    }
}


struct MySub1View: View {
    @ObservedObject var filterModel : FilterViewModel
    
    var body: some View {
        HStack(spacing:10) {
            VStack(alignment:.leading, spacing:20) {
                DatePicker(selection: $filterModel.dateFilter, displayedComponents: .date) {
                    Text("From")
                        .font(.body)
                        .fixedSize()
                }
            }
        }
    }
}

 

Ответ №2:

Это так просто, создайте массив и сохраните их все, не усложняйте свой код, если вы хотите экспортировать массив дат, а затем использовать StateObject, на самом деле это не большая проблема. в конце концов, тогда начните работать с вашим сохраненным массивом, например, где и как вы хотите его использовать!

 import SwiftUI

struct ContentView: View {

    var body: some View {
        
        mySub1View()

    }
}
 

 struct mySub1View: View {

    @State private var selection: Date = Date()
    @State private var selectionArray: [Date] = [Date]()
    
    var body: some View {

 if #available(iOS 14.0, *) {
        DatePicker(selection.description, selection: $selection, displayedComponents: .date)
            .onChange(of: selection) { newValue in
                
                selectionArray.append(newValue)
                print(selectionArray)
            }
      }
    }
}