检查数组是否包含对象并在SwiftUI中更新已发布的布尔值

时间:2020-09-19 13:37:49

标签: ios swift xcode swiftui combine

我有一个符合布尔值的ObservableObject的Day。 在白天,一共有3个班次。

在这3个数组中,只要有一个用户等于当前用户,我就会尝试更新视图。

当前尝试使用Combine,并且在显示视图时似乎可以使用,但是从所有shift.employees数组中删除当前用户后,它仍然为真。

我要观察的布尔值是hasShifts。如果为true,则应该是一个小圆圈指示器;如果为false,则应该为空。

我不知道我的错误在哪里,所以我在这里发布了与此问题相关的所有代码。另外,如果您有更好,更合适的方法来达到此效果,请告诉我。

Demo picture, deleted the user from every shift and the orange circle still exists.

主视图:

struct SetWeekdaysShiftsView: View {

@EnvironmentObject var session: SessionStore

var body: some View {
    ScrollView{
        WeekRow()
        ForEach(session.week){ day in
            ShiftTypesView(day: day)
        }
    }
}

包含班次的组框:


    struct ShiftTypesView: View{
    
    @ObservedObject var day: Day
    
    @State private var showAll = false
    
    @State private var buttonText = "Expand"

    var body: some View{
        if day.isSelected{
            GroupBox(label: HStack{
                Text(day.date ?? "")
                Spacer()
                Button {
                    withAnimation(.spring()){
                        self.showAll.toggle()
                        if self.showAll{
                            buttonText = "Collapse"
                        }else{
                            buttonText = "Expand"
                        }
                        for shift in day.shifts{
                            shift.isSelected.toggle()
                        }
                    }
                } label: {
                    Text(LocalizedStringKey(buttonText))
                        .font(.subheadline)
                }
            }) {
                Divider()
                withAnimation(.spring()){
                    ForEach(day.shifts){ shift in
                        
                        ShiftRow(shift: shift, show: $showAll)
                            .padding(8)
                            .background(Color(UIColor.systemGray6))
                            .cornerRadius(10)
                    }
                }
            }
            .padding(.horizontal)
            .padding(.bottom)
            .groupBoxStyle(RoundedGroupBoxStyle(paddingTop: false))
        }
    }
}

从同一班次的employees数组中删除所需的用户。


    fileprivate struct ShiftRow: View{
    
    @ObservedObject var shift: Shift
    
    @Binding var show: Bool
    
    var body: some View{
        DisclosureGroup(LocalizedStringKey(shift.type!.description()), isExpanded: $shift.isSelected ) {
            ForEach(shift.employees){ employee in
                EmployeeRow(employee: employee)
                    .onTapGesture {
                        withAnimation(.spring()){
                            if !self.shift.removedEmployees.contains(where: {$0.employeeId == employee.employeeId}){
                                removeEmployee(employee: employee)
                            }
                        }
                    }
            }
            HStack{
                Menu {
                    if shift.removedEmployees.count != 0{
                        ForEach(shift.removedEmployees){emp in
                            Button(emp.name){
                                withAnimation(.spring()){
                                    self.shift.employees.append(emp)
                                    self.shift.removedEmployees.removeAll(where: {$0.id == emp.id})
                                }
                            }
                        }
                    }
                } label: {
                    if self.shift.removedEmployees.count != 0{
                        Label(LocalizedStringKey("Add Employee"), systemImage: "plus.circle.fill")
                    }else{
                        Label(LocalizedStringKey("Add Employee"), systemImage: "plus.circle.fill")
                            .foregroundColor(Color.blue.opacity(0.3))
                    }
                }
                Spacer()
            }.padding(8)
            
        }
    }
    
    private func removeEmployee(employee: Employee){
        withAnimation(.spring()){
            if let index = self.shift.employees.lastIndex(where: {$0.id == employee.id}){
                print("Removed \(employee.name)")
                self.shift.employees.remove(at: index)
                self.shift.removedEmployees.append(employee)
            }
        }
    }
}

包含数据并发布以查看的日项目(工作日[其中有hasShift布尔值]):


    struct WeekItem: View {
    
    @StateObject var day: Day
    
    var body: some View {
        VStack{
            VStack(spacing: 8){
                Text(day.daySymbol)
                    .foregroundColor(.secondary)
                    .font(.callout)
                ZStack{
                    Circle()
                        .fill(day.isSelected ? Color.blue : Color.clear)
                        .frame(width: 30, height: 30, alignment: .center)
                        .scaleEffect(day.isSelected ? 1.2 : 1)
                        .animation(.spring(response: 0.3, dampingFraction: 0.6, blendDuration: 0))
                    Text(day.dayNumber)
                        .foregroundColor(day.isSelected ? Color.white : Color.secondary)
                        .font(.system(size: 15, weight: .bold, design: .rounded))
                }
            }
            Circle()
                .fill(day.isSelected ? Color.orange : Color.blue)
                .frame(width: 5, height: 5, alignment: .center)
//THIS IS THE BOOLEAN
                .opacity(day.hasShifts ? 1 : 0)
                .scaleEffect(day.isSelected ? 1.2 : 1)
                .animation(.spring(response: 0.3, dampingFraction: 0.6, blendDuration: 0))
        }
        
    }
}

一天的observableObject:

class Day: Codable, Identifiable, Hashable, ObservableObject{

    private var session = SessionStore.shared
    var id = UUID()
    @Published var shifts = [Shift].init(repeating: Shift(), count: 3)
    @Published var date: String?
    @Published var isSelected = false
    @Published var hasShifts = false
    @Published var daySymbol = ""
    @Published var dayNumber = ""
    var isApplied = false
    var timeStamp = Date().timeInterval
    
    private var cancellables = Set<AnyCancellable>()
    
    init(){
        
    }
    
    init(date: String, isSelected: Bool, hasShifts: Bool, daySymbol: String, dayNumber: String){
        self.date = date
        self.isSelected = isSelected
        self.hasShifts = hasShifts
        self.daySymbol = daySymbol
        self.dayNumber = dayNumber
    }

    func setShifts(morning: [Employee], middle: [Employee], evening: [Employee]){

        let morning = Shift(type: .Morning, employees: morning)
        let middle = Shift(type: .Middle, employees: middle)
        let evening = Shift(type: .Evening, employees: evening)

        self.shifts[0] = morning
        self.shifts[1] = middle
        self.shifts[2] = evening
        
        isApplied = true
        
        self.$shifts
            .map{ shifts in
                return shifts.contains(where: {$0.employees.contains(where: {$0.name == self.session.user?.name})})
            }
            .sink{ input in
                self.hasShifts = input
            }
            .store(in: &cancellables)
    }

从服务器以阵列形式接收所有员工后,在SessionStore中使用此功能实施7天阵列。 (列表)


    for (i, d) in date.weekDaySymbols.enumerated(){
                
                let day = Day(date: date.nextWeek[i], isSelected: false, hasShifts: false, daySymbol: d.uppercased(), dayNumber: date.nextWeekNumbers[i])
                
                day.setShifts(morning: list, middle: list, evening: list)
                
                if i == 0 {day.isSelected = true}
                
                self.week.append(day)
            }

0 个答案:

没有答案