---
title: DiscreteFormatStyle
framework: foundation
role: symbol
role_heading: Protocol
path: foundation/discreteformatstyle
---

# DiscreteFormatStyle

A format style that transforms a continuous input into a discrete output and provides information about its discretization boundaries.

## Declaration

```swift
protocol DiscreteFormatStyle<FormatInput, FormatOutput> : FormatStyle
```

## Overview

Overview Use this protocol to keep displays up to date if input changes continuously, or to iterate over all possible outputs of a FormatStyle by obtaining the next discrete input in either direction from discreteInput(before:) or discreteInput(after:). Ordering of Inputs The ordering over FormatInput defined by discreteInput(before:) / discreteInput(after:) must be consistent between the two functions. If FormatInput conforms to the Comparable protocol, the format style’s ordering should be consistent with the canonical ordering defined via the Comparable conformance, i.e. it should hold that discreteInput(before: x)! < x < discreteInput(after: x)! where discrete inputs are not nil. Stepping through Discrete Input/Output Pairs One use case of this protocol is enumerating all discrete inputs of a format style and their respective outputs. While the discreteInput(before:) and discreteInput(after:) functions are the right tool for that, they do not give a guarantee that their respective return values actually produce an output that is different from the output produced by formatting the input value used when calling discreteInput(before:) / discreteInput(after:), they only provide a value that produces a different output for most inputs. E.g. when formatting a floating point value as an integer, we can get the next discrete input after x by calculating floor(x + 1). However, when rounding toward zero, the whole interval (-1;1) formats as zero. It would be ok for a discrete format style to ignore that edge case and return 0 for the discreteInput(after:) a negative value greater than -1. Therefore, to enumerate all discrete input/output pairs, adjacent outputs must be deduplicated in order to guarantee no adjacent outputs are the same. The following example produces all discrete input/output pairs for inputs in a given range making sure adjacent outputs are unequal: extension DiscreteFormatStyle     where FormatInput : Comparable, FormatOutput : Equatable {         func enumerated(         in range: ClosedRange<FormatInput>     ) -> [(input: FormatInput, output: FormatOutput)] {         var input = range.lowerBound         var output = format(input)

var pairs = [(input: FormatInput, output: FormatOutput)]()         pairs.append((input, output))

// get the next discretization bound         while let nextInput = discreteInput(after: input),               // check that it is still in the requested `range`               nextInput <= range.upperBound {             // get the respective formatted output             let nextOutput = format(nextInput)             // deduplicate based on the formatted output             if nextOutput != output {                 pairs.append((nextInput, nextOutput))             }                 input = nextInput             output = nextOutput         }

return pairs     } } Imperfect Discretization Boundaries In some scenarios, a format style cannot provide precise discretization boundaries in a performant manner. In those cases it must override input(before:) and input(after:) to reflect that. For any discretization boundary x returned by either discreteInput(before:) or discreteInput(after:) based on the original input y, all values representable in the FormatInputstrictly  between x and the return value of input(after: x) or input(before: x), respectively, are not guaranteed to produce the same formatted output as y. The following schematic shows an overview of the guarantees given by the protocol: xB = discreteInput(before: y)       y      xA = discreteInput(after: y)       |                             |                             | <-----+---+-------------------------+-------------------------+---+--->           |                                                   |  zB = input(after: xB)                          zA = input(before: xA) the formatted output for everything in zB...zA (including bounds) is guaranteed to be equal to format(y) the formatted output for xB and lower is most likely different from format(y) the formatted output for xA and higher is most likely different from format(y) the  formatted output between xB and zB, as well as zA and xA (excluding bounds) cannot be predicted

## Topics

### Instance Methods

- [discreteInput(after:)](foundation/discreteformatstyle/discreteinput(after:).md)
- [discreteInput(before:)](foundation/discreteformatstyle/discreteinput(before:).md)
- [input(after:)](foundation/discreteformatstyle/input(after:).md)
- [input(before:)](foundation/discreteformatstyle/input(before:).md)

## Relationships

### Inherits From

- [Decodable](swift/decodable.md)
- [Encodable](swift/encodable.md)
- [Equatable](swift/equatable.md)
- [FormatStyle](foundation/formatstyle.md)
- [Hashable](swift/hashable.md)

### Conforming Types

- [Date.AnchoredRelativeFormatStyle](foundation/date/anchoredrelativeformatstyle.md)
- [Date.ComponentsFormatStyle](foundation/date/componentsformatstyle.md)
- [Date.FormatStyle](foundation/date/formatstyle.md)
- [Date.FormatStyle.Attributed](foundation/date/formatstyle/attributed-swift.struct.md)
- [Date.VerbatimFormatStyle](foundation/date/verbatimformatstyle.md)
- [Date.VerbatimFormatStyle.Attributed](foundation/date/verbatimformatstyle/attributed-swift.struct.md)

## See Also

### Protocols

- [NSKeyValueObservingCustomization](foundation/nskeyvalueobservingcustomization.md)
