Submission Date
2026-07-16
Status
Open
Area
Developer Documentation
Operating System Version
iOS 26
Type
Incorrect/Unexpected Behavior
Description
https://developer.apple.com/documentation/swiftui/landmarks-building-an-app-with-liquid-glass
In the provided sample project, the Landmark struct (which conforms to Hashable, Identifiable, and Transferable) implements custom Equatable and Hashable behavior by comparing and hashing only its id property:
static func == (lhs: Landmark, rhs: Landmark) -> Bool {
return lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
While equating identity (id) with equality (==) is a common mistake, doing so in an official Apple developer sample promotes a severe anti-pattern that directly breaks SwiftUI's rendering pipeline.
Why this is a bug:
SwiftUI relies on Equatable (==) to determine whether a view's input data has changed and if the view needs to be redrawn. Because this custom implementation asserts that two Landmark instances are equal if their IDs match, any changes to other properties (such as updating a name, a description, a photo, or a favorite status) will be ignored by SwiftUI. If a parent view passes a mutated Landmark to a child view, the child view will fail to re-evaluate or redraw because oldLandmark == newLandmark incorrectly evaluates to true.
Steps to Reproduce
- Download and run the sample project.
- Observe the custom == and hash(into:) overrides on the Landmark model struct.
- Pass a Landmark instance into a subview.
- Mutate any property of that landmark instance other than the id (e.g., toggle a boolean or change a text string).
- Notice that the subview observing the instance fails to update its UI because SwiftUI's diffing engine assumes no change occurred.
Expected Behavior
The Landmark model should use memberwise equality (comparing all properties that contribute to the visual representation of the landmark) so that SwiftUI can accurately detect property mutations and trigger UI redraws.
Suggested Fix
The safest and cleanest approach is to remove the manual == and hash(into:) implementations entirely.
Since all properties of Landmark conform to Hashable, removing these manual overrides allows the Swift compiler to synthesize the correct, highly optimized memberwise conformity automatically:
// Correct, simplified struct definition
struct Landmark: Hashable, Identifiable, Transferable {
var id: Int
var name: String
var park: String
var state: String
var description: String
// ... other properties
// (Manual == and hash(into:) implementations removed)
}
Letting the compiler handle this ensures that identity (Identifiable.id) is properly decoupled from value state equality (Equatable), resolving the rendering bugs.
Keywords
Sample Code
Prerequisites
Submission Date
2026-07-16
Status
Open
Area
Developer Documentation
Operating System Version
iOS 26
Type
Incorrect/Unexpected Behavior
Description
https://developer.apple.com/documentation/swiftui/landmarks-building-an-app-with-liquid-glass
In the provided sample project, the Landmark struct (which conforms to Hashable, Identifiable, and Transferable) implements custom Equatable and Hashable behavior by comparing and hashing only its id property:
While equating identity (id) with equality (==) is a common mistake, doing so in an official Apple developer sample promotes a severe anti-pattern that directly breaks SwiftUI's rendering pipeline.
Why this is a bug:
SwiftUI relies on Equatable (==) to determine whether a view's input data has changed and if the view needs to be redrawn. Because this custom implementation asserts that two Landmark instances are equal if their IDs match, any changes to other properties (such as updating a name, a description, a photo, or a favorite status) will be ignored by SwiftUI. If a parent view passes a mutated Landmark to a child view, the child view will fail to re-evaluate or redraw because oldLandmark == newLandmark incorrectly evaluates to true.
Steps to Reproduce
Expected Behavior
The Landmark model should use memberwise equality (comparing all properties that contribute to the visual representation of the landmark) so that SwiftUI can accurately detect property mutations and trigger UI redraws.
Suggested Fix
The safest and cleanest approach is to remove the manual == and hash(into:) implementations entirely.
Since all properties of Landmark conform to Hashable, removing these manual overrides allows the Swift compiler to synthesize the correct, highly optimized memberwise conformity automatically:
Letting the compiler handle this ensures that identity (Identifiable.id) is properly decoupled from value state equality (Equatable), resolving the rendering bugs.
Keywords
Sample Code
Prerequisites
FB<number>: <title>