Created
July 8, 2020 19:41
-
-
Save swiftui-lab/56e1cee404cb37163dc99dd307b22b1d to your computer and use it in GitHub Desktop.
Describes how anchor points work in .matechedGeometryEffect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension UnitPoint { | |
var anchorName: String { | |
switch self { | |
case .topLeading: return ".topLeading" | |
case .top: return ".top" | |
case .topTrailing: return ".topTrailing" | |
case .trailing: return ".trailing" | |
case .bottomTrailing: return ".bottomTrailing" | |
case .bottom: return ".bottom" | |
case .bottomLeading: return ".bottomLeading" | |
case .leading: return ".leading" | |
case .center: return ".center" | |
default: return "" | |
} | |
} | |
var alignment: Alignment { | |
switch self { | |
case .topLeading: return .topLeading | |
case .top: return .top | |
case .topTrailing: return .topTrailing | |
case .trailing: return .trailing | |
case .bottomTrailing: return .bottomTrailing | |
case .bottom: return .bottom | |
case .bottomLeading: return .bottomLeading | |
case .leading: return .leading | |
case .center: return .center | |
default: return .center | |
} | |
} | |
var dotOffset: CGSize { CGSize(width: (x - 0.5) * 2 * 5.0, height: (y - 0.5) * 2 * 5.0) } | |
} | |
struct ContentView: View { | |
@Namespace var ns | |
@State var anchorIdx = 0 | |
@State private var matched = false | |
let anchors: [UnitPoint] = [.topLeading, .top, .topTrailing, .trailing, .bottomTrailing, .bottom, .bottomLeading, .leading, .center] | |
let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect() | |
var body: some View { | |
VStack(spacing: 50) { | |
ZStack(alignment: .topLeading) { | |
Triangle(.down, .blue) | |
.overlay(Circle().fill(Color.red).frame(width: 10, height: 10).offset(UnitPoint.topLeading.dotOffset), alignment: .topLeading) | |
.matchedGeometryEffect(id: "id1", in: ns, anchor: .topLeading) | |
.frame(width: 75, height: 75) | |
Triangle(.right, .green) | |
.overlay( | |
Circle() | |
.fill(Color.yellow) | |
.frame(width: 10, height: 10) | |
.offset(anchors[anchorIdx].dotOffset) | |
, alignment: anchors[anchorIdx].alignment) | |
.matchedGeometryEffect(id: matched ? "id1" : "", in: ns, anchor: anchors[anchorIdx], isSource: false) | |
.frame(width: 75, height: 75) | |
.offset(y: matched ? 0 : -100) | |
} | |
Text("\(anchors[anchorIdx].anchorName)") | |
}.onReceive(timer) { _ in | |
withAnimation(.spring()) { | |
self.matched = false | |
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { | |
withAnimation(.easeInOut(duration: 0.5)) { | |
// cycle through the array indefenitely | |
anchorIdx = (anchorIdx + 1) % anchors.count | |
self.matched = true | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment