Skip to content

Commit

Permalink
Merge pull request #70 from RodBrown1988/fix/case-iterable-flags
Browse files Browse the repository at this point in the history
Fix case iterable flag appearance, selection and popping behaviour
  • Loading branch information
bok- authored Jan 4, 2021
2 parents 8314230 + 649af94 commit a1c08c8
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,27 @@ struct CaseIterableFlagControl<Value>: View where Value: FlagValue, Value: CaseI
let hasChanges: Bool
@Binding var showDetail: Bool

@State private var showPicker = false
@Binding var showPicker: Bool

// MARK: - View Body

#if os(iOS)

var body: some View {
VStack {
HStack {
NavigationLink(destination: self.selector, isActive: self.$showPicker) {
HStack {
Text(self.label).font(.headline)
Spacer()
FlagDisplayValueView(value: self.value)
}
HStack {
NavigationLink(destination: self.selector, isActive: self.$showPicker) {
HStack {
Text(self.label).font(.headline)
Spacer()
FlagDisplayValueView(value: self.value)
}
DetailButton(hasChanges: self.hasChanges, showDetail: self.$showDetail)
}
DetailButton(hasChanges: self.hasChanges, showDetail: self.$showDetail)
}
}

var selector: some View {
return self.selectorList
.listStyle(GroupedListStyle())
.navigationBarTitle(Text(self.label), displayMode: .inline)
}

Expand Down Expand Up @@ -80,20 +77,26 @@ struct CaseIterableFlagControl<Value>: View where Value: FlagValue, Value: CaseI
#endif

var selectorList: some View {
List(Value.allCases, id: \.self, selection: Binding(self.$value)) { value in
HStack {
FlagDisplayValueView(value: value)
Spacer()

if value == self.value {
self.checkmark
}
Form {
ForEach(Value.allCases, id: \.self) { value in
Button(
action: {
self.value = value
self.showPicker = false
},
label: {
HStack {
FlagDisplayValueView(value: value)
.foregroundColor(.primary)
Spacer()

if value == self.value {
self.checkmark
}
}
}
)
}
.contentShape(Rectangle())
.onTapGesture {
self.value = value
self.showPicker = false
}
}
}

Expand All @@ -118,14 +121,14 @@ struct CaseIterableFlagControl<Value>: View where Value: FlagValue, Value: CaseI

@available(OSX 11.0, iOS 13.0, watchOS 7.0, tvOS 13.0, *)
protocol CaseIterableEditableFlag {
func control<RootGroup> (label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>) -> AnyView where RootGroup: FlagContainer
func control<RootGroup> (label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>, showPicker: Binding<Bool>) -> AnyView where RootGroup: FlagContainer
}

@available(OSX 11.0, iOS 13.0, watchOS 7.0, tvOS 13.0, *)
extension UnfurledFlag: CaseIterableEditableFlag
where Value: FlagValue, Value: CaseIterable, Value.AllCases: RandomAccessCollection,
Value: RawRepresentable, Value.RawValue: FlagValue, Value: Hashable {
func control<RootGroup>(label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>) -> AnyView where RootGroup: FlagContainer {
func control<RootGroup>(label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>, showPicker: Binding<Bool>) -> AnyView where RootGroup: FlagContainer {
return CaseIterableFlagControl<Value> (
label: label,
value: Binding (
Expand All @@ -135,7 +138,8 @@ extension UnfurledFlag: CaseIterableEditableFlag
transformer: PassthroughTransformer<Value>.self
),
hasChanges: manager.hasValueInSource(flag: self.flag),
showDetail: showDetail
showDetail: showDetail,
showPicker: showPicker
)
.eraseToAnyView()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,27 @@ struct OptionalCaseIterableFlagControl<Value>: View
let hasChanges: Bool
@Binding var showDetail: Bool

@State private var showPicker = false
@Binding var showPicker: Bool

// MARK: - View Body

var body: some View {
VStack {
HStack {
NavigationLink(destination: self.selector, isActive: self.$showPicker) {
HStack {
Text(self.label).font(.headline)
Spacer()
FlagDisplayValueView(value: self.value.wrapped)
}
HStack {
NavigationLink(destination: self.selector, isActive: self.$showPicker) {
HStack {
Text(self.label).font(.headline)
Spacer()
FlagDisplayValueView(value: self.value.wrapped)
}
DetailButton(hasChanges: self.hasChanges, showDetail: self.$showDetail)
}
DetailButton(hasChanges: self.hasChanges, showDetail: self.$showDetail)
}
}

#if os(iOS)

var selector: some View {
return self.selectorList
.listStyle(GroupedListStyle())
.navigationBarTitle(Text(self.label), displayMode: .inline)
}

Expand All @@ -63,37 +60,38 @@ struct OptionalCaseIterableFlagControl<Value>: View
#endif

var selectorList: some View {
List {
Form {
Section {
HStack {
Text("None")
Spacer()
Button(
action: {
self.valueSelected(nil)
},
label: {
Text("None")
.foregroundColor(.primary)
Spacer()

if self.value.wrapped == nil {
self.checkmark
}
}
.contentShape(Rectangle())
.onTapGesture {
self.value.wrapped = nil
self.showPicker = false
if self.value.wrapped == nil {
self.checkmark
}
}
)
}

ForEach(Value.WrappedFlagValue.allCases, id: \.self) { value in
HStack {
FlagDisplayValueView(value: value)
Spacer()
Button(
action: {
self.valueSelected(value)
},
label: {
FlagDisplayValueView(value: value)
Spacer()

if value == self.value.wrapped {
self.checkmark
}
}
.contentShape(Rectangle())
.onTapGesture {
self.value.wrapped = value
self.showPicker = false
if value == self.value.wrapped {
self.checkmark
}
}
)
}
}
}
Expand All @@ -112,22 +110,27 @@ struct OptionalCaseIterableFlagControl<Value>: View

#endif

func valueSelected(_ value: Value.WrappedFlagValue?) {
self.value.wrapped = value
self.showPicker = false
}

}


// MARK: - Creating CaseIterableFlagControls

@available(OSX 11.0, iOS 13.0, watchOS 7.0, tvOS 13.0, *)
protocol OptionalCaseIterableEditableFlag {
func control<RootGroup> (label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>) -> AnyView where RootGroup: FlagContainer
func control<RootGroup> (label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>, showPicker: Binding<Bool>) -> AnyView where RootGroup: FlagContainer
}

@available(OSX 11.0, iOS 13.0, watchOS 7.0, tvOS 13.0, *)
extension UnfurledFlag: OptionalCaseIterableEditableFlag
where Value: OptionalFlagValue, Value.WrappedFlagValue: CaseIterable,
Value.WrappedFlagValue.AllCases: RandomAccessCollection, Value.WrappedFlagValue: RawRepresentable,
Value.WrappedFlagValue.RawValue: FlagValue, Value.WrappedFlagValue: Hashable {
func control<RootGroup>(label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>) -> AnyView where RootGroup: FlagContainer {
func control<RootGroup>(label: String, manager: FlagValueManager<RootGroup>, showDetail: Binding<Bool>, showPicker: Binding<Bool>) -> AnyView where RootGroup: FlagContainer {
let key = self.info.key

return OptionalCaseIterableFlagControl<Value> (
Expand All @@ -144,7 +147,8 @@ extension UnfurledFlag: OptionalCaseIterableEditableFlag
}
),
hasChanges: manager.hasValueInSource(flag: self.flag),
showDetail: showDetail
showDetail: showDetail,
showPicker: showPicker
)
.eraseToAnyView()
}
Expand Down
6 changes: 4 additions & 2 deletions Sources/Vexillographer/FlagView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ struct UnfurledFlagView<Value, RootGroup>: View where Value: FlagValue, RootGrou

@State private var showDetail = false

@State private var showPicker = false


// MARK: - Initialisation

Expand Down Expand Up @@ -54,10 +56,10 @@ struct UnfurledFlagView<Value, RootGroup>: View where Value: FlagValue, RootGrou
return flag.control(label: self.flag.info.name, manager: self.manager, showDetail: self.$showDetail)

} else if let flag = self.flag as? CaseIterableEditableFlag {
return flag.control(label: self.flag.info.name, manager: self.manager, showDetail: self.$showDetail)
return flag.control(label: self.flag.info.name, manager: self.manager, showDetail: self.$showDetail, showPicker: self.$showPicker)

} else if let flag = self.flag as? OptionalCaseIterableEditableFlag {
return flag.control(label: self.flag.info.name, manager: self.manager, showDetail: self.$showDetail)
return flag.control(label: self.flag.info.name, manager: self.manager, showDetail: self.$showDetail, showPicker: self.$showPicker)

} else if let flag = self.flag as? StringEditableFlag {
return flag.control(label: self.flag.info.name, manager: self.manager, showDetail: self.$showDetail)
Expand Down

0 comments on commit a1c08c8

Please sign in to comment.