|
// |
|
// NavPicker.swift |
|
// ColorCore Demo |
|
// |
|
// Created by Oliver Drobnik on 09.02.21. |
|
// |
|
|
|
import SwiftUI |
|
|
|
public struct NavPicker<Label, Items> : View where Label : View, Items: CustomStringConvertible & Identifiable |
|
{ |
|
let selection: Binding<Int?> |
|
let items:[Items] |
|
let label: Label |
|
let firstIndexToShow: Int |
|
|
|
public init(selection: Binding<Int?>, label: Label, items: [Items], firstIndexToShow: Int = 0) |
|
{ |
|
self.selection = selection |
|
self.label = label |
|
self.items = items |
|
self.firstIndexToShow = firstIndexToShow |
|
} |
|
|
|
public var body: some View |
|
{ |
|
NavigationLink( |
|
destination: NavPickerDetail(selection: selection, items: items, firstIndexToShow: firstIndexToShow) |
|
.toolbar { ToolbarItem(placement: .principal) { label } }) { |
|
HStack { |
|
label |
|
Spacer() |
|
if let index = selection.wrappedValue |
|
{ |
|
Text(items[index].description) |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
public struct NavPickerDetail<Items> : View where Items: CustomStringConvertible & Identifiable |
|
{ |
|
@Binding var selection: Int? |
|
var items:[Items] |
|
@State var firstIndexToShow: Int = 0 |
|
|
|
@State var highlightedIndex: Int? |
|
|
|
@Environment(\.presentationMode) var presentationMode |
|
|
|
public var body: some View |
|
{ |
|
List { |
|
ForEach(firstIndexToShow..<items.count) { index in |
|
|
|
HStack { |
|
Text(items[index].description) |
|
Spacer() |
|
} |
|
.contentShape(Rectangle()) |
|
.onTapGesture { |
|
self.selection = index |
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { |
|
self.presentationMode.wrappedValue.dismiss() |
|
} |
|
} |
|
.onLongPressGesture(minimumDuration: .greatestFiniteMagnitude, maximumDistance: .greatestFiniteMagnitude, pressing: { self.highlightedIndex = $0 ? index : nil }) {} |
|
.modifier(CheckmarkModifier(checked: index == selection)) |
|
.background(Color(UIColor.opaqueSeparator) |
|
.opacity(highlightedIndex == index ? 1.0 : 0.0) |
|
.padding(EdgeInsets(top: -12, leading: -16, bottom: -12, trailing: -16)) |
|
) |
|
} |
|
} |
|
.listStyle(GroupedListStyle()) |
|
} |
|
} |
|
|
|
|
|
struct CheckmarkModifier: ViewModifier { |
|
var checked: Bool = false |
|
func body(content: Content) -> some View { |
|
Group { |
|
if checked { |
|
ZStack(alignment: .trailing) { |
|
content |
|
Image(systemName: "checkmark") |
|
.resizable() |
|
.frame(width: 16, height: 16) |
|
.shadow(radius: 1) |
|
.foregroundColor(Color.accentColor) |
|
} |
|
} else { |
|
content |
|
} |
|
} |
|
} |
|
} |