In TextField, how to ensure the binding and the output of the formatter are of the same type?

203 Views Asked by At

In my app, I have a custom TextField to set the port number. I want to validate the user input and set a UInt16.

This is my code:

import SwiftUI

struct TextFieldPort: View {
    @Binding var port: UInt16
    var defaultPort: UInt16
    let formatter = NumberFormatter()
    
    init(port: Binding<UInt16>, defaultPort: UInt16) {
        self._port = port
        self.defaultPort = defaultPort
        formatter.minimum = 0
        formatter.maximum = 65535
        formatter.numberStyle = .none
    }
    
    var body: some View {
        TextField("\(formatter.string(from: defaultPort as NSNumber) ?? "0")", value: $port, formatter: formatter)
    }
}

The view does what it should. Values above 65535 and below 0 are rejected and the previous value remains.

PROBLEM:

Setting values above the UInt16 range, I get a purple triangle warning in XCode, e.g.:

The value 65.536 is too large.

When the enclosing Popover closes, I get another purple triangle warning returned from PopoverWindow.close():

Failure setting binding's value. The supplied formatter does not produce values of type UInt16. This may be resolved by ensuring the binding and the output of the formatter are of the same type.

QUESTION:

How can I make sure to match the formatter output type with my binding? (And do I have to worry about the warnings?)

0

There are 0 best solutions below