SwiftUI обновляет CustomView при изменении переменной enum - PullRequest
0 голосов
/ 20 февраля 2020

У меня месячный обзор по сетке 3х4. Каждое подпредставление представляет собой небольшую коробку с названием месяца и состоянием, выбрано / не выбрано . Проблема в том ... Я хочу наблюдать переменную enum из родительского представления и отменить выбор всех кнопок, кроме последнего нажатого.

На данный момент у меня реализованы следующие логики c. Изначально у меня currentMonthSelected с состоянием .none (месяцы не выбраны) . Когда я нажимаю кнопку JAN , я передаю currentMonthSelected == .jax на Подмножество одного месяца , и он возвращает мне обратный вызов, который изменяет currentMonthSelected, которое должно наблюдать другие представления.

ParentView

@State var currentMonthSelected: MonthsTypes = .none

SingleButtonView(title: .jan, isSelected: currentMonthSelected == .jan ? true : false, action: { month in
   self.currentMonthSelected = month
})

SingleButtonView(title: .feb, isSelected: currentMonthSelected == .feb ? true : false, action: { month in
   self.currentMonthSelected = month
})

Подмесячный просмотр за месяц

struct SingleButtonView: View {
var title: MonthsTypes = .none
@State var isSelected = false
var action: (MonthsTypes) -> ()
var body: some View {
    VStack(spacing: 0){
        Button(action: {
            self.action(self.title)
        }){
            Spacer()
            Text(title.rawValue.prefix(3))
                .font(.Montserrat(weight: isSelected ? .SemiBold : .Regular, size: 16))
                .foregroundColor(isSelected ? Color.white : Color.gray)
            Spacer()
        }
    }
        .frame(width: 80, height: 40)
        .background(isSelected ? Color.white : Color.brand_purple)
}
}

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020
enum MonthsTypes: String {
    case jan = "January"
    case feb = "February"
    case none
}

struct ContentView: View {
    @State var currentMonthSelected: MonthsTypes = .none

    var body: some View {
        VStack() {
            SingleButtonView(title: .jan, currentMonthSelected: $currentMonthSelected)

            SingleButtonView(title: .feb, currentMonthSelected: $currentMonthSelected)}

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct SingleButtonView: View {
    var title: MonthsTypes = .none
    @Binding var currentMonthSelected: MonthsTypes
    var isSelected: Bool {
        if title == currentMonthSelected { return true}
        return false
    }
    var body: some View {
        VStack(spacing: 0){
            Button(action: {
                self.currentMonthSelected = self.title
            }){
                Spacer()
                Text(title.rawValue.prefix(3))
                    .foregroundColor(isSelected ? Color.white : Color.gray)
                Spacer()
            }
        }
        .frame(width: 80, height: 40)
        .background(isSelected ? Color.white : Color.yellow)
    }
}
0 голосов
/ 20 февраля 2020

Такой иерархией представлений намного проще управлять с помощью одной модели представлений. Вот демонстрация подхода, основанного на вашем коде (просто пропустите несколько строк с пользовательскими шрифтами / цветами, что, однако, не влияет на идею).

struct ParentView_Previews: PreviewProvider {
    static var previews: some View {
        ParentView().environmentObject(ViewModel()) // inject view model
    }
}

enum MonthsTypes: String { // restored enum
    case none = "None"
    case jan = "January"
    case feb = "February"
    case mar = "March"
}

class ViewModel: ObservableObject { // selection holder (extendable for anything)
    @Published var currentMonthSelected: MonthsTypes = .none
}

struct ParentView: View {
    @EnvironmentObject var viewModel: ViewModel // assuming injected by .environmentObject(ViewModel)

    var body: some View {
        VStack {
            SingleButtonView(title: .jan) // simple declaration, action can be added
            SingleButtonView(title: .feb)
            SingleButtonView(title: .mar)
        }
    }
}

struct SingleButtonView: View {
    @EnvironmentObject var vm: ViewModel // logic on selection change is inside

    var title: MonthsTypes = .none
    var action: (MonthsTypes) -> () = { _ in } // default action does nothing

    var body: some View {
        VStack(spacing: 0){
            Button(action: {
                // change selection to self or toggle
                self.vm.currentMonthSelected = (self.vm.currentMonthSelected != self.title ? self.title : MonthsTypes.none)

                self.action(self.title) // callback if needed
            }){
                Spacer()
                Text(title.rawValue.prefix(3))
                    .foregroundColor(self.vm.currentMonthSelected == self.title ? Color.white : Color.gray)
                Spacer()
            }
        }
        .frame(width: 80, height: 40)
        .background(vm.currentMonthSelected == title ? Color.purple : Color.white)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...