Skip to content

Commit d4a825d

Browse files
authored
Fix DynamicLayoutMap index issue (#580)
1 parent 6ce7922 commit d4a825d

File tree

3 files changed

+61
-16
lines changed

3 files changed

+61
-16
lines changed

Example/OpenSwiftUIUITests/Layout/Stack/ZStackIndexUITests.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import SnapshotTesting
1010
@Suite(.snapshots(record: .never, diffTool: diffTool))
1111
struct ZStackIndexUITests {
1212
@Test
13-
func zIndexExample() {
13+
func rotateOverlap() {
1414
struct ContentView: View {
1515
var body: some View {
1616
VStack {
@@ -30,11 +30,9 @@ struct ZStackIndexUITests {
3030
}
3131
}
3232
}
33-
withKnownIssue {
34-
openSwiftUIAssertSnapshot(
35-
of: ContentView(),
36-
size: CGSize(width: 200, height: 200)
37-
)
38-
}
33+
openSwiftUIAssertSnapshot(
34+
of: ContentView(),
35+
size: CGSize(width: 200, height: 200)
36+
)
3937
}
4038
}

Sources/OpenSwiftUICore/Layout/Dynamic/DynamicLayoutMap.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,23 @@ package struct DynamicLayoutMap {
3131
map.first(where: { $0.id == id })?.value ?? .init()
3232
}
3333
set {
34-
let index = map.firstIndex(where: { $0.id == id })
35-
if let index {
36-
if newValue.isEmpty {
37-
map.remove(at: index)
38-
} else {
39-
map[index].value = newValue
40-
}
41-
} else {
34+
if map.isEmpty {
4235
if !newValue.isEmpty {
4336
map.insert((id, newValue), at: 0)
4437
}
38+
} else {
39+
let index = map.lowerBound { $0.id < id }
40+
if index != map.count, map[index].id == id {
41+
if newValue.isEmpty {
42+
map.remove(at: index)
43+
} else {
44+
map[index].value = newValue
45+
}
46+
} else {
47+
if !newValue.isEmpty {
48+
map.insert((id, newValue), at: index)
49+
}
50+
}
4551
}
4652
sortedSeed = .zero
4753
}

Tests/OpenSwiftUICoreTests/Layout/ZIndexTests.swift

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
// OpenSwiftUICoreTests
44

55
import OpenAttributeGraphShims
6-
@_spi(ForOpenSwiftUIOnly)
76
import OpenSwiftUICore
87
import Testing
8+
import Foundation
99

1010
@MainActor
1111
struct ZIndexTests {
@@ -16,4 +16,45 @@ struct ZIndexTests {
1616
collection.zIndex = 1.5
1717
#expect(collection.zIndex.isApproximatelyEqual(to: 1.5))
1818
}
19+
20+
#if canImport(Darwin)
21+
@Test
22+
func zIndexDisplayList() {
23+
struct ContentView: View {
24+
var body: some View {
25+
GeometryReader { proxy in
26+
VStack {
27+
Color.white
28+
.frame(width: 100, height: 100, alignment: .center)
29+
.zIndex(1)
30+
Color.black
31+
.frame(width: 100, height: 100, alignment: .center)
32+
}
33+
.frame(width: 200, height: 200)
34+
}
35+
.ignoresSafeArea()
36+
}
37+
}
38+
let graph = ViewGraph(
39+
rootViewType: ContentView.self,
40+
requestedOutputs: [.layout, .displayList]
41+
)
42+
graph.instantiateOutputs()
43+
graph.setRootView(ContentView())
44+
graph.setProposedSize(CGSize(width: 1000, height: 1000))
45+
let (displayList, _) = graph.displayList()
46+
let expectRegex = try! Regex(#"""
47+
\(display-list
48+
\(item #:identity \d+ #:version \d+
49+
\(frame \(50.0 104.0; 100.0 100.0\)\)
50+
\(content-seed \d+\)
51+
\(color #000000FF\)\)
52+
\(item #:identity \d+ #:version \d+
53+
\(frame \(50.0 -4.0; 100.0 100.0\)\)
54+
\(content-seed \d+\)
55+
\(color #FFFFFFFF\)\)\)
56+
"""#)
57+
#expect(displayList.description.contains(expectRegex))
58+
}
59+
#endif
1960
}

0 commit comments

Comments
 (0)