Skip to content

Instantly share code, notes, and snippets.

@markiv
Last active November 7, 2019 17:46
Show Gist options
  • Save markiv/a71b51e821b5041a097a4c243dddf95e to your computer and use it in GitHub Desktop.
Save markiv/a71b51e821b5041a097a4c243dddf95e to your computer and use it in GitHub Desktop.
Playing with a combined stepper and text field for entering numeric quantities
//
// ContentView.swift
// QuantityStepper
//
// Created by Vikram Kriplaney on 07.11.2019.
// Copyright © 2019 iPhonso GmbH. All rights reserved.
//
import SwiftUI
extension ClosedRange {
func clamp(_ value: Bound) -> Bound {
return self.lowerBound > value ? self.lowerBound
: self.upperBound < value ? self.upperBound
: value
}
}
extension View {
func endEditing(_ force: Bool = false) {
UIApplication.shared.windows.forEach { $0.endEditing(force) }
}
}
struct QuantityStepper: View {
struct StepperButtonStyle: ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(.primary)
.padding(11)
.padding(.horizontal, 6)
.background(Color(.tertiarySystemFill))
.cornerRadius(8)
}
}
@Binding var value: Int
var bounds: ClosedRange<Int> = 0...999
func increment() {
endEditing()
value = bounds.clamp(value + 1)
}
func decrement() {
endEditing()
value = bounds.clamp(value - 1)
}
var stringValue: Binding<String> {
Binding<String>(
get: { "\(self.value)" },
set: { self.value = self.bounds.clamp(Int($0) ?? 0) }
)
}
var body: some View {
HStack(spacing: 4) {
Image(systemName: "minus")
.modifier(StepperButtonStyle())
.onTapGesture(perform: decrement)
TextField("Qty", text: stringValue)
.textFieldStyle(RoundedBorderTextFieldStyle())
.multilineTextAlignment(.center)
.keyboardType(.numberPad)
.frame(width: 60)
Image(systemName: "plus")
.modifier(StepperButtonStyle())
.onTapGesture(perform: increment)
}
}
}
struct ContentView: View {
@State var quantities = Array(repeating: 0, count: 16)
var body: some View {
NavigationView {
List(0 ..< quantities.count, id: \.self) { index in
Text("Product #\(1 + index)")
Spacer()
QuantityStepper(value: self.$quantities[index])
}.navigationBarTitle("Shopping List")
.navigationBarItems(trailing: Text("\(quantities.reduce(0, +)) items"))
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment