Last active
August 31, 2021 23:55
-
-
Save mattyoung/9b1c81419bbd7ceb3039278d8ef02b62 to your computer and use it in GitHub Desktop.
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
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