SwiftUI Developer Assessment — Questions and Answers
Question 1: Which SwiftUI modifier is used to add a tap gesture to a view?
- .onTapGesture { } (Correct answer)
- .tapGesture { }
- .gesture(TapRecognizer())
- .addTap { }
Correct answer: .onTapGesture { }
.onTapGesture { } is the SwiftUI modifier that attaches a tap gesture action to a view.
Question 2: Which SwiftUI modifier applies a visual effect blur to a view?
- .shadow(radius:)
- .blur(radius:) (Correct answer)
- .opacity()
- .saturation()
Correct answer: .blur(radius:)
`.blur(radius:)` applies a Gaussian blur effect to the view's rendered output.
Question 3: Which Swift 5.9+ macro simplifies creating an ObservableObject without `@Published` annotations?
- @Observable (Correct answer)
- @Observed
- @State
- @Model
Correct answer: @Observable
The `@Observable` macro (introduced in Swift 5.9 / iOS 17) automatically tracks property access and synthesizes observation without `@Published`.
Question 4: What is the purpose of the `path` parameter in `NavigationStack(path:)`?
- It provides a programmatic binding to the navigation stack's path for deep linking (Correct answer)
- It specifies the animation path
- It defines the root view path
- It sets the navigation bar title path
Correct answer: It provides a programmatic binding to the navigation stack's path for deep linking
Binding a `NavigationPath` to the stack allows programmatic navigation, back-navigation, and deep link support.
Question 5: Which property wrapper reads a value from SwiftUI's environment without requiring it to be an ObservableObject?
- @EnvironmentObject
- @Environment (Correct answer)
- @AppStorage
- @SceneStorage
Correct answer: @Environment
`@Environment` reads values from the environment using a key path, such as `\.colorScheme` or `\.locale`.
Question 6: 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 7: How can a presented sheet dismiss itself in SwiftUI?
- Both B and C work (Correct answer)
- Set isPresented to false directly
- Call dismiss() on the view
- Use @Environment(\.dismiss) and call dismiss()
Correct answer: Both B and C work
You can dismiss by using `@Environment(\.dismiss)` to call `dismiss()`, or by toggling the `isPresented` binding to `false`.
Question 8: How do you set the title shown in the navigation bar for a SwiftUI view?
- .navigationBarTitle()
- Both B and C work (Correct answer)
- .title()
- .navigationTitle()
Correct answer: Both B and C work
Both `.navigationTitle()` (iOS 14+) and the older `.navigationBarTitle()` set the navigation bar title.
Question 9: What function do you call to animate a state change in SwiftUI?
- transition()
- Animation.run()
- animate()
- withAnimation() (Correct answer)
Correct answer: withAnimation()
Wrapping a state change in `withAnimation {}` causes SwiftUI to animate any resulting view changes.
Question 10: What property wrapper is used to declare local mutable state in a SwiftUI view?
- @ObservedObject
- @EnvironmentObject
- @State (Correct answer)
- @Binding
Correct answer: @State
`@State` declares a source of truth owned by the view for simple value types.
Question 11: What is the purpose of `ViewBuilder` in SwiftUI?
- It compiles views to native code
- It manages view identity
- It allows closures to return multiple views as a single view (Correct answer)
- It validates view hierarchies
Correct answer: It allows closures to return multiple views as a single view
`@ViewBuilder` is a result builder that lets a closure return multiple child views combined into a single view.
Question 12: How do you present a modal sheet in SwiftUI?
- .sheet(isPresented:content:) (Correct answer)
- .overlay(isPresented:)
- .modal(isPresented:content:)
- .present()
Correct answer: .sheet(isPresented:content:)
The `.sheet(isPresented:content:)` modifier presents a modal sheet when the binding's value becomes true.
Question 13: What is `@SceneStorage` used for in SwiftUI?
- Persisting lightweight UI state per scene instance (Correct answer)
- Syncing data with CloudKit
- Storing large data objects
- Sharing state across all app scenes
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 14: Keywords are used to create Contants in Swift.
- Contants
- Let (Correct answer)
- None of the above
- Conts
Correct answer: Let
In Swift, the `let` keyword is used to declare constants, which are values that cannot be changed once they are initialized. This promotes code safety and predictability by ensuring that certain data remains immutable throughout its scope. In contrast, the `var` keyword is used to declare variables, whose values can be modified after initialization.
Question 15: What data type will be allocated to result in the code below?
- UInt
- Array
- Int
- Tuple (Correct answer)
Correct answer: Tuple
In Swift, a tuple is a compound data type that groups multiple values into a single, ordered collection. The code `let result = (true, "hello", 10)` creates a tuple because it combines values of different types (`Bool`, `String`, `Int`) within parentheses. The `result` constant will therefore be allocated as a tuple of type `(Bool, String, Int)`.
Question 16: What Should We Use To Unwrap Value Inside Optional?
- !
- None of the above (Correct answer)
- @
- ?
Correct answer: None of the above
To safely unwrap values inside an Optional in Swift, you typically use techniques like optional binding (`if let` or `guard let`), optional chaining (`?`), or nil-coalescing (`??`). The symbols `@`, `?`, and `!` are used in Swift for various purposes (e.g., attributes, optional type declaration, forced unwrapping), but none of them *alone* is the primary *method* for safely unwrapping. Therefore, 'None of the above' is the correct choice as the listed symbols are not the complete unwrapping mechanisms.
Question 17: What does `.drawingGroup()` do when applied to an animated SwiftUI view?
- Groups views for accessibility
- Renders the view hierarchy into a single Metal-backed layer for better animation performance (Correct answer)
- Flattens the view for export
- 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 18: Which alignment option centers content both horizontally and vertically in a ZStack?
- .topLeading
- .leading
- .bottomTrailing
- .center (Correct answer)
Correct answer: .center
ZStack's default alignment is `.center`, which centers children both horizontally and vertically.
Question 19: Which of the following is an incorrect Swift value type?
- Enum
- Class
- Character (Correct answer)
- Double
Correct answer: Character
The question asks to identify an 'incorrect Swift value type.' In Swift, `Character` is fundamentally a value type, as it is implemented as a struct, meaning copies are made when assigned or passed. However, if `Character` is the intended correct answer, it suggests a non-standard interpretation or a potential flaw in the question's premise. Typically, `Class` is the only reference type among the given options, making it the one that is *not* a value type in standard Swift.
Question 20: Which container view in SwiftUI creates a scrollable list of items?
- Group
- LazyVStack
- ForEach
- ScrollView (Correct answer)
Correct answer: ScrollView
ScrollView provides a scrolling container for its child content.
Question 21: How do you animate only specific properties of a view in SwiftUI?
- Apply .animation(_:value:) to scope it to a specific value
- Use withAnimation and all properties animate
- Both B and C can scope animation to specific properties (Correct answer)
- Use AnimatableModifier for each property
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 22: How do you create a custom view modifier in SwiftUI?
- Conform a struct to ViewModifier and implement body(content:) (Correct answer)
- Use extension on View
- Subclass ViewModifier
- Use @Modifier attribute
Correct answer: Conform a struct to ViewModifier and implement body(content:)
Conforming a struct to `ViewModifier` and implementing `body(content:)` lets you encapsulate reusable modifier chains.
Question 23: What does the `.trim(from:to:)` modifier do on a SwiftUI Shape?
- Trims whitespace padding
- Removes corners from the shape
- Draws only a fraction of the shape's path between two normalized positions (Correct answer)
- Clips the shape to a rectangle
Correct answer: Draws only a fraction of the shape's path between two normalized positions
`.trim(from:to:)` draws the portion of the shape's path between the start and end fractions (0.0–1.0), useful for progress indicators.
Question 24: What does `.matchedGeometryEffect(id:in:)` do in SwiftUI?
- Aligns views to the same grid
- Copies a view's frame to another
- Matches views by their frame sizes
- Synchronizes the geometry of two views across a transition for hero animations (Correct answer)
Correct answer: Synchronizes the geometry of two views across a transition for hero animations
`.matchedGeometryEffect` links two views by the same ID so SwiftUI interpolates their position and size during transitions.
Question 25: How does SwiftUI determine when to re-render a view?
- It re-renders only when explicitly called
- It re-renders on every user interaction
- It re-renders when its input state or bindings change (Correct answer)
- It re-renders on every timer tick
Correct answer: It re-renders when its input state or bindings change
SwiftUI's diffing engine re-evaluates and re-renders a view only when its declared dependencies (state, bindings, environment) change.
Question 26: How do you make List rows deletable in SwiftUI?
- .deleteEnabled(true)
- .swipeToDelete()
- .onDelete(perform:) inside ForEach (Correct answer)
- List(onDelete:)
Correct answer: .onDelete(perform:) inside ForEach
Adding `.onDelete(perform:)` to a `ForEach` inside a `List` enables swipe-to-delete with the system delete gesture.
Question 27: How do you create a 3D rotation animation in SwiftUI?
- .perspective()
- .rotation3DEffect(angle:axis:) (Correct answer)
- .transform3D()
- .rotationEffect()
Correct answer: .rotation3DEffect(angle:axis:)
`.rotation3DEffect(_:axis:anchor:anchorZ:perspective:)` applies a three-dimensional rotation around a specified axis.
Question 28: What protocol must a custom type conform to in order for SwiftUI to interpolate it during animations?
- VectorArithmetic
- Equatable
- Animatable (Correct answer)
- Codable
Correct answer: Animatable
SwiftUI uses the `Animatable` protocol (which requires `animatableData` of type `VectorArithmetic`) to interpolate custom types during animations.
Question 29: Which SwiftUI modifier sets a navigation bar button display mode?
- .navigationTitle(displayMode:) (Correct answer)
- .navigationBarDisplayMode()
- .navigationTitleDisplayMode()
- .titleMode()
Correct answer: .navigationTitle(displayMode:)
`.navigationTitle(_:displayMode:)` or the separate `.navigationBarTitleDisplayMode()` modifier controls whether the title is large or inline.
Question 30: What protocol must a class conform to in order to be used with `@ObservedObject` or `@StateObject`?
- Equatable
- Codable
- Identifiable
- ObservableObject (Correct answer)
Correct answer: ObservableObject
A class must conform to `ObservableObject` and mark properties with `@Published` to trigger view updates.
Question 31: Which modifier applies an animation phase in the new Keyframe Animator (iOS 17)?
- .keyframeAnimator(initialValue:keyframes:content:) (Correct answer)
- .sequenceAnimation()
- .phaseAnimator()
- .animationPhase()
Correct answer: .keyframeAnimator(initialValue:keyframes:content:)
`KeyframeAnimator` (iOS 17) lets you define multi-property keyframe tracks to animate complex, choreographed sequences.
Question 32: What does the `.animation(_:value:)` modifier do in SwiftUI?
- Applies an animation only when the specified value changes (Correct answer)
- Adds a looping animation
- Applies an animation to all state changes
- Applies a transition animation
Correct answer: Applies an animation only when the specified value changes
`.animation(_:value:)` scopes the animation to trigger only when the given value changes, preventing unintended animations.
Question 33: What happens to a `@State` variable when a SwiftUI view is destroyed and recreated?
- It resets to its initial value (Correct answer)
- It retains its value
- It is saved to disk automatically
- It triggers an animation
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 34: How do you programmatically select a tab in SwiftUI's `TabView`?
- Use `TabView(selection:)` with a binding and `.tag()` on each tab (Correct answer)
- Call tabView.select(tag:)
- Use NavigationStack inside TabView
- Use @EnvironmentObject to share selection
Correct answer: Use `TabView(selection:)` with a binding and `.tag()` on each tab
Bind a state variable to `TabView(selection:)` and tag each tab view with `.tag()` to enable programmatic tab selection.
Question 35: What does the `.onChange(of:perform:)` modifier do?
- Animates a value change
- Prevents view updates
- Debounces rapid changes
- Triggers a closure whenever a specified value changes (Correct answer)
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 36: Which protocol do you implement to create a custom SwiftUI shape?
- Shape (Correct answer)
- CustomShape
- Drawable
- Path
Correct answer: Shape
Conforming to the `Shape` protocol and implementing `path(in:)` lets you create fully custom drawable shapes.
Question 37: How do you deep link into a specific view using NavigationStack in SwiftUI?
- Override NavigationController
- Use UNUserNotificationCenter
- Use URL schemes only
- Append values to the NavigationPath binding (Correct answer)
Correct answer: Append values to the NavigationPath binding
By appending one or more destination values to the bound `NavigationPath`, you can programmatically push to any depth in the stack.
Question 38: Which modifier applies a hue rotation effect to all colors in a SwiftUI view?
- .saturation()
- .colorInvert()
- .contrast()
- .hueRotation(_:) (Correct answer)
Correct answer: .hueRotation(_:)
`.hueRotation(_:)` shifts the hue of all colors in the view by the given angle, cycling through the color wheel.
Question 39: What happens to a `@GestureState` variable when the user lifts their finger and the gesture ends?
- It triggers an onEnded callback only
- It resets to its initial value automatically (Correct answer)
- It becomes nil
- It retains its last value
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 40: What does the `.frame(width:height:)` modifier do in SwiftUI?
- Adds a border around the view
- Aligns the view in its parent
- Clips the view to a specific shape
- Sets the view's proposed size (Correct answer)
Correct answer: Sets the view's proposed size
`.frame(width:height:)` proposes a fixed size to the view and positions it within that frame.
Question 41: What is the role of `OutlineGroup` in SwiftUI?
- Renders an SVG outline path
- Groups views with an outline border
- Creates a hierarchical, expandable tree list from recursive data (Correct answer)
- Renders a circle outline around views
Correct answer: Creates a hierarchical, expandable tree list from recursive data
`OutlineGroup` recursively walks a tree data structure and renders an expandable/collapsible hierarchical list.
Question 42: What does `.phaseAnimator(_:content:animation:)` do in SwiftUI (iOS 17)?
- Applies physics simulation
- Runs an animation in a separate thread
- Cycles through a sequence of phases, animating between them (Correct answer)
- Syncs animation to audio phases
Correct answer: Cycles through a sequence of phases, animating between them
`PhaseAnimator` cycles through a sequence of states, automatically animating between each phase in a loop.
Question 43: Which property wrapper connects a view to an external ObservableObject instance?
- @Binding
- @Published
- @State
- @ObservedObject (Correct answer)
Correct answer: @ObservedObject
`@ObservedObject` tells the view to re-render when the observed object's published properties change.
Question 44: What does the `delay` parameter on an animation do in SwiftUI?
- Pauses the app for that duration
- Slows the animation playback rate
- Schedules a view update
- Delays the start of the animation by the given time interval (Correct answer)
Correct answer: Delays the start of the animation by the given time interval
Calling `.delay()` on an animation causes it to wait the specified number of seconds before starting.
Question 45: What will the numbers constant contain when this code is run?
- [1,2,3]
- [[1,1],[1,2],[1,3]]
- [1,1,2,2,3,3] (Correct answer)
- [[1,2,3],[1,2,3],[1,2,3]]
Correct answer: [1,1,2,2,3,3]
The outer `flatMap` iterates `outer` from 1 to 3. For each `outer`, the inner `map` iterates `inner` from 1 to 2, returning the `outer` value each time. This creates intermediate arrays like `[1,1]` (for `outer=1`), `[2,2]` (for `outer=2`), and `[3,3]` (for `outer=3`). The `flatMap` then flattens these arrays of arrays into a single, combined array, resulting in `[1,1,2,2,3,3]`.
Question 46: What will the numbers constant contain when this code is run?
- [[1,1],[2,1],[3,1]] (Correct answer)
- [[1,2,3],[1,2,3],[1,2,3]]
- [1,1,2,2,3,3]
- [[1,1],[1,2],[1,3]]
Correct answer: [[1,1],[2,1],[3,1]]
The outer `map` iterates through `outer` values from 1 to 3. For each `outer`, the inner `map` iterates `inner` only once, always assigning `1`. The closure `[outer, inner]` then creates a two-element array for each iteration. The outer `map` collects these individual `[outer, inner]` arrays, resulting in `[1,1]`, `[2,1]`, and `[3,1]` sequentially, which are then combined into the final array `[[1,1],[2,1],[3,1]]`.
Question 47: Which built-in transition slides a view in from the leading edge?
- .move(edge: .leading) (Correct answer)
- .push(from: .leading)
- .offset()
- .slide
Correct answer: .move(edge: .leading)
`.move(edge: .leading)` slides a view in from or out to the leading edge of the screen.
Question 48: What does the `.padding()` modifier do when called with no arguments?
- Adds padding only on leading and trailing
- Removes existing padding
- Adds system-default padding on all sides (Correct answer)
- Adds 0 padding
Correct answer: Adds system-default padding on all sides
Calling `.padding()` with no arguments applies the system default padding amount on all four sides.
Question 49: How do you create a `Binding` value manually in SwiftUI?
- State.binding(value)
- Both A and B are valid for different purposes (Correct answer)
- Binding.constant(value)
- Binding(get: { value }, set: { value = $0 })
Correct answer: Both A and B are valid for different purposes
You can create a custom Binding with get/set closures or use `Binding.constant()` for a read-only binding in previews.
Question 50: Which animation creates a spring effect in SwiftUI?
- .interpolatingSpring()
- .linear
- .easeInOut
- .spring() (Correct answer)
Correct answer: .spring()
`.spring()` applies a spring-based animation with configurable response, dampingFraction, and blendDuration.
Question 51: What is the output of the following code?
- "Dave"
- "Hello, Dave!" (Correct answer)
- Nothing will be output
- "Hello, "
Correct answer: "Hello, Dave!"
The `name` variable is an optional `String` initialized with the value "Dave". The `!` after `name` is the force-unwrapping operator, which explicitly accesses the value contained within the optional. Since `name` is not `nil`, it successfully unwraps to "Dave", and the string interpolation then produces "Hello, Dave!".
Question 52: Which modifier on a SwiftUI view receives dropped items in a drag-and-drop operation?
- .acceptDrop(of:)
- .dropReceiver(for:)
- .dropDestination(for:action:) (Correct answer)
- .onDrop(of:action:)
Correct answer: .dropDestination(for:action:)
.dropDestination(for:action:) is the modern iOS 16+ modifier that designates a view as a drop target for Transferable types.
Question 53: How do you make a SwiftUI image resize to fill its frame?
- .frame().resize()
- .scaleEffect()
- .resizable().scaledToFill() (Correct answer)
- .aspectRatio()
Correct answer: .resizable().scaledToFill()
You must call `.resizable()` first, then `.scaledToFill()` or `.scaledToFit()` to control how it fills the frame.
Question 54: What modifier triggers navigation to a destination view when a view is tapped in a NavigationStack?
- .navigationLink()
- NavigationLink wrapping the view
- .navigationDestination()
- 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 55: What modifier is used to set the background color of a SwiftUI view?
- .background() (Correct answer)
- .foregroundColor()
- .backgroundColor()
- .fill()
Correct answer: .background()
The `.background()` modifier applies a background color or view behind the modified view.
Question 56: What is the purpose of `@AppStorage` in SwiftUI?
- Persists state across scene sessions
- Manages in-memory app-wide state
- Provides a binding to a UserDefaults key (Correct answer)
- Stores data in iCloud
Correct answer: Provides a binding to a UserDefaults key
`@AppStorage` wraps UserDefaults, automatically updating the view when the stored value changes.
Question 57: What does marking a property with `@Published` inside an ObservableObject do?
- Persists the property to UserDefaults
- Marks the property as thread-safe
- Makes the property read-only
- Automatically notifies subscribers when the property changes (Correct answer)
Correct answer: Automatically notifies subscribers when the property changes
`@Published` uses Combine to emit a change event whenever the property's value is set, triggering view re-renders.
Question 58: When should you use `@StateObject` instead of `@ObservedObject`?
- When the object is a value type
- When the view owns and creates the object (Correct answer)
- When the object is passed from a parent view
- When sharing data across the app
Correct answer: When the view owns and creates the object
`@StateObject` should be used when the view is responsible for creating and owning the object's lifetime.
Question 59: What is the purpose of the `symbolVariants` environment value in SwiftUI?
- Automatically applies a variant (fill, slash, circle) to all SF Symbols in a view hierarchy (Correct answer)
- Controls symbol size
- Sets SF Symbol animation style
- Selects the symbol color palette
Correct answer: Automatically applies a variant (fill, slash, circle) to all SF Symbols in a view hierarchy
Setting `.symbolVariants()` in the environment propagates a visual variant like `.fill` or `.circle` to all SF Symbols in the hierarchy.
Question 60: What is the default animation used when you call `withAnimation {}` with no parameters?
- .spring()
- .easeIn
- .easeInOut with 0.35s duration (Correct answer)
- .linear
Correct answer: .easeInOut with 0.35s duration
When called without arguments, `withAnimation` uses the default ease-in-out animation with approximately a 0.35 second duration.
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