Pattern · Forms

New

Address Form SwiftUI Block

A shipping or billing address form with AutoFill, a searchable country list, per-country labels and street suggestions.

The address section of a checkout, account or delivery screen. Every line carries its AutoFill type, the country opens a searchable list and relabels the region and postal code for it, and street suggestions from MapKit fill the city, region and postal code when picked. Fields check on Save and then live, and Save shows working, done and failed.

  • SwiftUI
  • iOS 17.0+
  • address-form
Get SwiftPieces Pro

$199 once, every piece included. See how installing works · Sign in

01

What's included

SwiftUI source you own, built on Apple frameworks only.

  • AutoFill types on every line
  • A searchable list of every country and region
  • State and ZIP code, County and Postcode, labelled for the country
  • Street suggestions from MapKit that fill the rest of the address
  • Checks on Save then live, Set as default, and Save with its states

02

Implementation notes

How it behaves, what it handles, and the decisions behind it.

One card holds the fields, each with its label inside its well above what's typed: Full name, Country or region, Street address, Apt, suite or floor, City, the region beside the postal code, and Phone. Every line carries its AutoFill type, so the keyboard offers the person's own address. Country or region opens a sheet listing every country and region in the person's language, with search, and the region and postal code relabel themselves for it: State and ZIP code in the United States, County and Postcode in the United Kingdom, Province and Postal code in Canada, and no region at all where addresses leave it out. As the street is typed, matching addresses drop down over the fields below it, from MapKit by default; picking one fills the street, city, region and postal code and moves on to the apartment line. Fields check themselves when Save address is tapped, then live as they're corrected, and the first one with a problem takes focus. Set as default is a switch on its own card. Save runs your closure with a spinner, a check, or the thrown error's message under it. Pass nil while a saved address loads and the block draws grey shapes in its own layout.

Notes

  • AddressForm(address:search:countryCodes:saveTitle:onSave:onSuccess:). Only address and onSave are required. It is a section: no navigation stack, background, padding or scroll view of its own, so place it in your own column or sheet.
  • AddressForm.Address holds fullName, countryCode (ISO 3166, "US"), street, line2, city, region, postalCode, phone and isDefault. Start a new one with Address(countryCode:). Address.sample is Maya's new address from the preview and Address.filled a complete one.
  • onSave receives the address with every field trimmed and the postal code uppercased. Return to succeed, throw to fail; a thrown LocalizedError's errorDescription shows under the button, otherwise "Couldn't save this address. Try again." A CancellationError goes back to rest quietly. onSuccess is called once the check has shown; go back or close your sheet there.
  • Checks on Save: a name, a street and a city; the region where the country needs one; the postal code where it's required, with a 5 or 9 digit check for ZIP codes; and a phone, when given, of at least 7 digits with its area code. Phone and Apt are optional.
  • AddressForm.Format.format(for:) gives a country's labels, prompts, which parts are required and whether the postal code is digits only. It covers the United States, United Kingdom, Ireland, Canada, Australia, Japan, India, the countries that call it a province, and the European countries that leave the region out; others read Region and Postal code, both optional.
  • search is an AddressForm.AddressSearch: a suggest closure that receives what's typed (3 characters or more, after a short pause) and the country code and returns Suggestions (an id, title and subtitle), and a resolve closure that turns a pick into an Address, of which the street, city, region, postal code and country are used. .mapKit, the default, uses MKLocalSearchCompleter for suggestions and MKLocalSearch to resolve them. Pass your own provider to use your address service, or nil to turn suggestions off. A failed lookup says "Couldn't look up that address. Type it in instead."
  • countryCodes limits the list to the countries you ship to. Nil offers every region in Locale.Region.isoRegions.
  • saveTitle defaults to "Save address".
  • AutoFill: .name, .streetAddressLine1, .streetAddressLine2, .addressCity, .addressState, .postalCode and .telephoneNumber. Return moves down the form and Done on the phone saves. ZIP codes and other numeric postal codes get the numbers keyboard.
  • Haptics: a selection tick when a suggestion fills the fields, a warning when Save finds a problem, success and error when the save lands or fails.
  • VoiceOver reads each field by its label with its error as a hint, the country row as a button with the country as its value, each suggestion as one element, and announces refused saves, a filled address and "Address saved". At accessibility sizes the region and postal code stack and suggestions wrap.
  • Reduce Motion turns every change into a short fade.
  • AddressFormExample at the end of AddressForm.swift is the Shipping address screen from the preview, with a stand-in search that offers three addresses on Market Street so every run is the same. Leave search out in your app to use MapKit. It reads the theme from the environment; pass wrapsInNavigationStack: false to push it in your own stack.

Theming

  • Reads SPTheme from @Environment(\.spTheme) and requires the design-system item.
  • The fields card and the default card are color.surface with radius.lg and 16 point padding; wells sit 12 points apart, groups 24.
  • Wells are at least 52 points tall on fill with radius.md and a 1 point separator hairline that turns to textPrimary when focused and to danger on an error. Labels inside them are type.caption in textSecondary (danger on an error), input type.body in textPrimary, prompts textTertiary, errors type.footnote in danger.
  • Suggestions float on surfaceElevated with a separator ring and spShadow(.e3), the one place the block lifts; rows lead with a mappin.and.ellipse symbol in textSecondary, titles type.body, subtitles type.footnote.
  • The switch is accent with an accentOn thumb when on and fill when off. Save address is accent with accentOn in type.headline, radius.md, 52 points.
  • The country sheet lists rows on surface with separator lines and a textPrimary check, tinted textPrimary.
  • States move with motion.snappy, filled fields and loading with motion.smooth, presses with motion.standard.

Requirements

  • Network access for the default MapKit search. No Info.plist key or location permission is needed.