Pattern · Forms
NewFeedback Form SwiftUI Block
A send-feedback section: a five-step rating, topic chips, a message, screenshots, device info and a thank-you.
The send-feedback section of a Help or Settings screen. A numbered rating, Bug, Idea, Billing and Other chips that change the message's prompt, up to three screenshots from the system picker, and Include device info that lists exactly what it sends. Send checks for a topic and a message, shows its working and failed states, and a thank-you replaces the form once it lands.
- SwiftUI
- iOS 17.0+
- feedback-form
$199 once, every piece included. See how installing works · Sign in
01
What's included
SwiftUI source you own, built on Apple frameworks only.
- A five-step rating from Not great to Love it
- Topic chips that change the message's prompt
- Up to three screenshots from the system picker, removable
- Include device info that shows exactly what it sends
- An optional reply email when signed out, and a thank-you with Done
02
Implementation notes
How it behaves, what it handles, and the decisions behind it.
The first card asks "How's it going?" with five numbered segments from "Not great" to "Love it"; tapping one fills it in ink, tapping it again clears it. The second asks "What's it about?" with Bug, Idea, Billing and Other as chips, and the message under them asks the question that fits the topic ("What happened, and what did you expect instead?" for a bug) with a count toward its limit. The third holds Screenshots, up to three thumbnails from the system photo picker with a remove button each and an Add tile, and Include device info, which lists exactly what it adds: app version, system, device and language. When the person is signed out an optional email for a reply follows. Send feedback checks that a topic and a message are there, then live as they're fixed, runs your closure with a spinner, and shows the thrown error's message under it if it fails. Once it lands, a thank-you replaces the form, saying where a reply would go, with Done to close.
Notes
FeedbackForm(topics:accountEmail:deviceDetails:messageLimit:maxScreenshots:onSend:onDone:). OnlyonSendis 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.onSendreceives aFeedbackForm.Submission: therating(1 to 5, or nil), the chosentopicid, the trimmedmessage,screenshotsas JPEG data at most 1600 points on the longest side in the order attached,deviceDetailswhen included, andreplyEmail(the account's, the one typed, or nil). Return to succeed, throw to fail; a thrownLocalizedError'serrorDescriptionshows under the button, otherwise "Couldn't send your feedback. Try again." ACancellationErrorgoes back to rest quietly.topicsis a list ofFeedbackForm.Topic, each anid,title, SF Symbol and the messagepromptit brings.Topic.defaultsis.bug,.idea,.billingand.other.accountEmailis where replies go for a signed-in person, and the thank-you names it. Leave it out and the block asks for an optional email, checked for its shape when given.deviceDetailsis what Include device info sends, asDeviceDetaillabel and value pairs. Leave it out forFeedbackForm.currentDeviceDetails(): the app's version and build from the bundle, the system name and version, the model identifier and the language. The toggle starts on and the list shows under it, so nothing is sent unseen.messageLimitdefaults to 1000 characters;maxScreenshotsto 3, and 0 hides screenshots.onDoneis called by Done on the thank-you; close your sheet there. The form resets either way.- Haptics: a selection tick for the rating and topic, a warning when Send finds something missing, success when it lands, an error when it fails or a picked image can't be read.
- VoiceOver reads each segment as "4 of 5, Good" with the selected trait, chips by their titles with the selected trait, the message count as "69 of 1000 characters", each thumbnail with its Remove screenshot button, and each device line as one element. It announces refused sends, removed screenshots and "Feedback sent. Thank you." Screenshot tiles shrink at accessibility sizes and every control is at least 44 points tall.
- Reduce Motion turns every change into a short fade.
FeedbackFormExampleat the end ofFeedbackForm.swiftis the Send feedback screen from the preview, for a signed-in person, with fixed device details so every run reads the same. It reads the theme from the environment; passwrapsInNavigationStack: falseto push it in your own stack.
Theming
- Reads
SPThemefrom@Environment(\.spTheme)and requires thedesign-systemitem. - Cards are
color.surfacewithradius.lgand 16 point padding, 24 points apart; card titles aretype.headline, "Optional" and the screenshot counttype.footnoteintextTertiary. - Rating segments are 48 points tall at
radius.smonfillwith aseparatorring; the chosen one istextPrimarywithsurfacefigures. Topic chips are capsules the same way, withtype.subheadmedium labels. Selection stays in ink so the accent belongs to Send. - The message is a well on
fillatradius.mdwith aseparatorhairline that turns totextPrimarywhen focused and todangeron an error; inputtype.body, prompttextTertiary, counttype.captionwith monospaced digits. - Thumbnails and the Add tile are 64 by 96 points at
radius.smwith aseparatorring; the remove button is a 22 pointsurfacecircle with atextPrimarycross. The device list sits onfillintype.footnote. - The switch is
accentwith anaccentOnthumb. Send feedback and Done areaccentwithaccentOnintype.headline,radius.md, 52 points. - The thank-you title uses the display face (
type.face) at 20 points, capped at semibold, with acheckmark.circleintextPrimaryand the line under it intype.subheadtextSecondary. - States move with
motion.snappy, the thank-you withmotion.smooth, presses withmotion.standard.
03
Keep building
Pieces that work well next to this one.