Skip to content

Instantly share code, notes, and snippets.

@mattyoung
Last active August 31, 2021 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattyoung/9b1c81419bbd7ceb3039278d8ef02b62 to your computer and use it in GitHub Desktop.
Save mattyoung/9b1c81419bbd7ceb3039278d8ef02b62 to your computer and use it in GitHub Desktop.
import SwiftUI
// the matched geometry effect works in this version
struct MyGizmo: View {
@State private var setting = 1
@Namespace private var namespace
var body: some View {
HStack {
ForEach(1...3, id: \.self) { item in
Button { setting = item }
label: {
Text("\(item)")
.foregroundColor(.primary)
.frame(maxWidth: .infinity)
.background { highlighter(item) }
// .animation(.default, value: setting) // works here
}
.animation(.default, value: setting) // works here
}
}
}
@ViewBuilder
func highlighter(_ item: Int) -> some View {
if setting == item {
RoundedRectangle(cornerRadius: 5)
.fill(Color(uiColor: .secondarySystemBackground))
.matchedGeometryEffect(id: "highlighter", in: namespace)
}
}
}
// exactly the same as above except use ButtonStyle
// now matched geometry effect doesn't work anymore, no matter where .animation() is placed
struct MyGizmoWithButtonStyle: View {
@State private var setting = 1
var body: some View {
HStack {
ForEach(1...3, id: \.self) { item in
Button("\(item)") { setting = item }
.buttonStyle(MyButtonStyle(setting: setting, item: item))
}
}
}
struct MyButtonStyle: ButtonStyle {
let setting: Int
let item: Int
@Namespace private var namespace
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)
.background { highlighter }
.animation(.default, value: setting) // doesn't work
}
@ViewBuilder
var highlighter: some View {
if setting == item {
RoundedRectangle(cornerRadius: 5)
.fill(Color(uiColor: .secondarySystemBackground))
.matchedGeometryEffect(id: "highlighter", in: namespace)
}
}
}
}
// Using ViewModifier matchedGeometryEffect() do not work also
struct MyGizmoWithViewModifier: View {
@State private var setting = 1
var body: some View {
HStack {
ForEach(1...3, id: \.self) { item in
Button { setting = item }
label: {
Text("\(item)")
.modifier(MyViewModifier(setting: setting, item: item))
}
}
}
}
struct MyViewModifier: ViewModifier {
let setting: Int
let item: Int
@Namespace private var namespace
func body(content: Content) -> some View {
content
.foregroundColor(.primary)
.frame(maxWidth: .infinity)
.background { highlighter }
.animation(.default, value: setting)
}
@ViewBuilder
var highlighter: some View {
if setting == item {
RoundedRectangle(cornerRadius: 5)
.fill(Color(uiColor: .secondarySystemBackground))
.matchedGeometryEffect(id: "highlighter", in: namespace)
}
}
}
}
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Text("Hello, world!")
.padding()
MyGizmo()
MyGizmoWithButtonStyle()
MyGizmoWithViewModifier()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment