One Logo Pool Ball
Foundation · IOS API REFERENCE

DiscreteFormatStyle

protocol · iOS 18.0+ · SDK 27.1

protocol DiscreteFormatStyle<FormatInput, FormatOutput> : FormatStyle

A format style that transforms a continuous input into a discrete output and provides information about its discretization boundaries. 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 ``FormatStyle/FormatInput`` defined by ``discreteInput(before:)`` / ``discreteInput(after:)`` must be consistent between the two functions. If ``FormatStyle/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: ```swift 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 ``FormatStyle/FormatInput``strictly 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

Members (0)

This type has no directly callable members in this snapshot. See the framework’s skipped declarations for unsupported APIs.

Skipped declarations

8 declarations were excluded from these bindings. Each reason comes from the generator or the iOS SDK compiler.

DiscreteFormatStyle.input(before:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(after:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(before:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(after:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(before:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(after:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(before:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

DiscreteFormatStyle.input(after:)

The iOS SDK compiler rejected this binding: member 'input' cannot be used on value of type 'any DiscreteFormatStyle'; consider using a generic constraint instead [#ExistentialMemberAccess]

All Foundation types →