SwiftUI Developer Assessment — Questions and Answers
Question 1: What property wrapper is used to declare local mutable state in a SwiftUI view?
- @EnvironmentObject
- @Binding
- @ObservedObject
- @State (Correct answer)
Correct answer: @State
`@State` declares a source of truth owned by the view for simple value types.
Question 2: How do you add a custom transition using `AnyTransition` in SwiftUI?
- Implement the Transition protocol
- Use AnyTransition.modifier(active:identity:) (Correct answer)
- Use withAnimation and custom offsets only
- Subclass Animation
Correct answer: Use AnyTransition.modifier(active:identity:)
`AnyTransition.modifier(active:identity:)` lets you define a custom transition using ViewModifier states for the active and identity states.
Question 3: How do you render an SF Symbol in SwiftUI?
- Icon(sf: "star")
- Image(systemName: "star") (Correct answer)
- SFSymbol("star")
- Symbol("star")
Correct answer: Image(systemName: "star")
`Image(systemName:)` loads and renders an SF Symbol by its system name.
Question 4: What happens to a `@GestureState` variable when the user lifts their finger and the gesture ends?
- It becomes nil
- It resets to its initial value automatically (Correct answer)
- It retains its last value
- It triggers an onEnded callback only
Correct answer: It resets to its initial value automatically
@GestureState automatically resets to the initial value declared at the property when the gesture ends, without any extra code.
Question 5: Which of the following methods for creating a raw string in Swift is correct?
- #"Hello, World!"# (Correct answer)
- `Hello, World!`
- """Hello, World!"""
- @"Hello, World!"
Correct answer: #"Hello, World!"#
Swift 5 introduced raw strings, which are created by enclosing the string literal within one or more hash symbols (`#`). This syntax, like `"#Hello, World!#"`, allows backslashes and other special characters within the string to be treated as literal text rather than escape sequences. This is particularly useful for regular expressions or file paths where escaping many characters would be cumbersome.
Question 6: Which SwiftUI modifier presents an alert?
- .alert(_:isPresented:actions:)
- .dialog(isPresented:)
- Both work (different iOS versions) (Correct answer)
- .alert(isPresented:content:)
Correct answer: Both work (different iOS versions)
Both the older `.alert(isPresented:content:)` and the newer `.alert(_:isPresented:actions:)` modifier signatures work depending on the iOS deployment target.
Question 7: What is `NavigationPath` used for in iOS 16+ SwiftUI navigation?
- Defining URL routes for the app
- Caching previous view states
- A type-erased list of navigation destinations enabling programmatic stack control (Correct answer)
- Animating navigation transitions
Correct answer: A type-erased list of navigation destinations enabling programmatic stack control
`NavigationPath` is a type-erased collection you bind to a `NavigationStack` to push, pop, or jump to any destination programmatically.
Question 8: What does the `.transition()` modifier control in SwiftUI?
- The sequence of animations
- How a view animates continuously
- How a view enters and exits the view hierarchy (Correct answer)
- The animation curve applied to a view
Correct answer: How a view enters and exits the view hierarchy
`.transition()` defines the animation applied when a view is inserted into or removed from the view hierarchy.
Question 9: What does the `.onChange(of:perform:)` modifier do?
- Triggers a closure whenever a specified value changes (Correct answer)
- Animates a value change
- Debounces rapid changes
- Prevents view updates
Correct answer: Triggers a closure whenever a specified value changes
`.onChange(of:perform:)` observes a value and calls the closure with the new value each time it changes.
Question 10: Which SwiftUI view overlays its children on top of each other?
- VStack
- HStack
- ZStack (Correct answer)
- List
Correct answer: ZStack
ZStack layers its child views along the Z-axis, drawing them on top of one another.
Question 11: Which framework is the reactive foundation underlying SwiftUI's data flow?
- Combine (Correct answer)
- PromiseKit
- RxSwift
- Foundation
Correct answer: Combine
SwiftUI's property wrappers like `@Published` and `@ObservedObject` are built on Apple's Combine framework.
Question 12: What happens to a `@State` variable when a SwiftUI view is destroyed and recreated?
- It triggers an animation
- It resets to its initial value (Correct answer)
- It is saved to disk automatically
- It retains its value
Correct answer: It resets to its initial value
SwiftUI resets `@State` to its initial value each time the view's identity changes and it is recreated.
Question 13: What is the purpose of `@AppStorage` in SwiftUI?
- Stores data in iCloud
- Persists state across scene sessions
- Manages in-memory app-wide state
- Provides a binding to a UserDefaults key (Correct answer)
Correct answer: Provides a binding to a UserDefaults key
`@AppStorage` wraps UserDefaults, automatically updating the view when the stored value changes.
Question 14: Which modifier adds a drop shadow to a SwiftUI view?
- .shadow() (Correct answer)
- .elevation()
- .shade()
- .dropShadow()
Correct answer: .shadow()
The `.shadow(color:radius:x:y:)` modifier renders a shadow behind the view.
Question 15: What modifier triggers navigation to a destination view when a view is tapped in a NavigationStack?
- .navigationDestination()
- NavigationLink wrapping the view
- .navigationLink()
- Both B and C depending on iOS version (Correct answer)
Correct answer: Both B and C depending on iOS version
In iOS 16+ you can use `NavigationLink` or the data-driven `.navigationDestination(for:destination:)` modifier to navigate.
Question 16: How do you make a SwiftUI image resize to fill its frame?
- .resizable().scaledToFill() (Correct answer)
- .aspectRatio()
- .scaleEffect()
- .frame().resize()
Correct answer: .resizable().scaledToFill()
You must call `.resizable()` first, then `.scaledToFill()` or `.scaledToFit()` to control how it fills the frame.
Question 17: How do you animate only specific properties of a view in SwiftUI?
- Both B and C can scope animation to specific properties (Correct answer)
- Apply .animation(_:value:) to scope it to a specific value
- Use AnimatableModifier for each property
- Use withAnimation and all properties animate
Correct answer: Both B and C can scope animation to specific properties
You can scope animations with `.animation(_:value:)` for simple cases, or implement `AnimatableModifier` for fully custom animatable data.
Question 18: How do you apply a linear gradient as a fill in SwiftUI?
- .fill(LinearGradient(colors:startPoint:endPoint:))
- Both A and C work (Correct answer)
- .gradient(.linear)
- .background(LinearGradient(...))
Correct answer: Both A and C work
You can apply a LinearGradient via `.fill()` on a Shape or via `.background()` on any view.
Question 19: What is `@SceneStorage` used for in SwiftUI?
- Sharing state across all app scenes
- Persisting lightweight UI state per scene instance (Correct answer)
- Storing large data objects
- Syncing data with CloudKit
Correct answer: Persisting lightweight UI state per scene instance
`@SceneStorage` persists small amounts of UI state tied to a specific scene, restoring it when the scene is recreated.
Question 20: How do you present a modal sheet in SwiftUI?
- .modal(isPresented:content:)
- .present()
- .sheet(isPresented:content:) (Correct answer)
- .overlay(isPresented:)
Correct answer: .sheet(isPresented:content:)
The `.sheet(isPresented:content:)` modifier presents a modal sheet when the binding's value becomes true.
Question 21: What is the purpose of the `@GestureState` property wrapper in SwiftUI?
- To define the initial state of a gesture
- To track gesture history
- To persist gesture data across app sessions
- To store transient gesture values that reset when the gesture ends (Correct answer)
Correct answer: To store transient gesture values that reset when the gesture ends
@GestureState automatically resets to its initial value when the gesture ends, making it ideal for transient interaction state.
Question 22: Which List style makes rows appear as separated inset cards?
- .listStyle(.sidebar)
- .listStyle(.insetGrouped) (Correct answer)
- .listStyle(.plain)
- .listStyle(.grouped)
Correct answer: .listStyle(.insetGrouped)
`.listStyle(.insetGrouped)` applies the inset grouped style, rendering sections as rounded-corner card groups.
Question 23: Which property wrapper reads a value from SwiftUI's environment without requiring it to be an ObservableObject?
- @SceneStorage
- @EnvironmentObject
- @AppStorage
- @Environment (Correct answer)
Correct answer: @Environment
`@Environment` reads values from the environment using a key path, such as `\.colorScheme` or `\.locale`.
Question 24: What does applying `.colorMultiply(_:)` do to a SwiftUI view?
- Multiplies each pixel's color by the given color (Correct answer)
- Inverts the colors
- Multiplies the view's opacity
- Converts to grayscale
Correct answer: Multiplies each pixel's color by the given color
`.colorMultiply(_:)` applies a color multiplication blend mode that tints the view by multiplying its pixel colors with the given color.
Question 25: What modifier enables drag-to-reorder rows in a SwiftUI List?
- .draggable()
- .onMove(perform:) (Correct answer)
- .onReorder()
- .moveDisabled(false)
Correct answer: .onMove(perform:)
`.onMove(perform:)` added to a `ForEach` inside a `List` enables the drag reorder handle when the list is in edit mode.
Question 26: What is the `@Namespace` property wrapper used for in SwiftUI?
- Defining matched geometry namespaces for hero animations (Correct answer)
- Creating view namespaces to avoid name collisions
- Storing animation references
- Scoping state variables
Correct answer: Defining matched geometry namespaces for hero animations
`@Namespace` creates an animation namespace used with `.matchedGeometryEffect()` to animate shared geometry between views.
Question 27: What does `.drawingGroup()` do when applied to an animated SwiftUI view?
- Flattens the view for export
- Renders the view hierarchy into a single Metal-backed layer for better animation performance (Correct answer)
- Groups views for accessibility
- Prevents re-renders
Correct answer: Renders the view hierarchy into a single Metal-backed layer for better animation performance
`.drawingGroup()` composites the view and its children into a single offscreen image using Metal, improving performance for complex animations.
Question 28: Which Swift compiler directive will cause an error to be generated?
- !error
- @error
- $error
- #error (Correct answer)
Correct answer: #error
The `#error` compiler directive in Swift is specifically designed to generate a custom compile-time error. When the Swift compiler encounters `#error "Your message"`, it immediately halts the build process and displays the provided error message. This is useful for enforcing build conditions or marking incomplete code sections that must be addressed.
Question 29: What function do you call to animate a state change in SwiftUI?
- Animation.run()
- transition()
- withAnimation() (Correct answer)
- animate()
Correct answer: withAnimation()
Wrapping a state change in `withAnimation {}` causes SwiftUI to animate any resulting view changes.
Question 30: Which built-in transition slides a view in from the leading edge?
- .push(from: .leading)
- .offset()
- .slide
- .move(edge: .leading) (Correct answer)
Correct answer: .move(edge: .leading)
`.move(edge: .leading)` slides a view in from or out to the leading edge of the screen.
SwiftUI Developer Assessment
SwiftUI is Apple's declarative UI framework for building apps across all Apple platforms. This assessment tests proficiency in building user interfaces, managing state and data flow, handling navigation, animations, gestures, and custom drawing using SwiftUI.
Exam Rules
- You can skip questions and return to them later
- Flag questions for review before submitting
- No feedback shown until you submit the entire exam
- Unanswered questions count as wrong — answer everything
- 10 pretest questions are mixed in and don't affect your score
- Timer auto-submits when time runs out
- Your progress is auto-saved every 30 seconds