在创建动画逻辑时,当按下按钮时,卡片会滑开,但是,使用状态和绑定的当前方法不会发生任何事情。 我想这里的技巧是我不让卡片视图知道按钮何时被触发。 这是
@State private var isFLipped = false
的按钮:
Button(action: {
// Handle button action
// isTapped.toggle()
isFLipped.toggle()
}) {
Text("👍")
.frame(width: 70, height: 50)
.background(Color("Easy"))
.clipShape(RoundedRectangle(cornerRadius: 8))
}
这是 SingleCardView:
ZStack {
RoundedRectangle(cornerRadius: 25, style: .continuous)
.fill(Color.white)
.overlay(RoundedRectangle(cornerRadius: 25).stroke(getColor(), lineWidth: 2))// Here we change the border color based on the swipe direction
.shadow(radius: 3)
VStack {
NavigationStack {
Text(card.term ?? "Unnamed Card")
Divider()
if isTapped {
Text(card.definition ?? "Unnamed Card")
}
}
}
}
.frame(width: 300, height: 500)
.rotation3DEffect(
Angle(degrees: isFLipped ? 360: 0),
axis: (x: 0, y: isFLipped ? 360 : 0, z: 0)
)
.onTapGesture {
isTapped.toggle()
}
}
执行此操作的 SwiftUI 方法/最有效的方法是在
@State
中拥有一个值类型,并将 isFlipped
共享为 @Binding
import SwiftUI
struct SampleSharedManagerView: View {
@State private var isFlipped: Bool = false
var body: some View {
NavigationStack{
List {
Section("first") {
FirstView(isFlipped: $isFlipped)
}
Section("second") {
SecondView(isFlipped: $isFlipped)
}
}
}
}
}
struct FirstView: View {
@Binding var isFlipped: Bool
var body: some View {
Image(systemName: "person")
.rotation3DEffect(Angle(degrees: isFlipped ? 360: 0), axis: (x: 0, y: isFlipped ? 360 : 0, z: 0))
.animation(.easeInOut(duration: 2), value: isFlipped)
}
}
struct SecondView: View {
@Binding var isFlipped: Bool
var body: some View {
Button("Toggle") {
isFlipped.toggle()
}.buttonStyle(.borderedProminent)
}
}
但是,如果我们假设这 2 个视图被不同的层分开,我们就可以利用
Combine
并拥有共享的事实来源。
import SwiftUI
import Combine
class AppEventsManager {
static let shared = AppEventsManager()
var isFlipped : CurrentValueSubject<Bool, Never> = .init(true)
private init() { }
}
然后您可以订阅需要它们的视图中的更改。
//Observes changes
struct FirstView: View {
@State private var isFlipped: Bool = false
@State private var cancellables: Set<AnyCancellable> = []
var body: some View {
Image(systemName: "person")
.rotation3DEffect(Angle(degrees: isFlipped ? 360: 0), axis: (x: 0, y: isFlipped ? 360 : 0, z: 0))
.animation(.easeInOut(duration: 2), value: isFlipped)
.task {
AppEventsManager.shared.isFlipped
.receive(on: DispatchQueue.main)
.sink { isFlipped in
self.isFlipped = isFlipped
}
.store(in: &cancellables)
}.onDisappear {
self.cancellables = .init()
}
}
}
//Makes Changes
struct SecondView: View {
let manager = AppEventsManager.shared
var body: some View {
Button("Toggle") {
manager.isFlipped.send(!manager.isFlipped.value)
}.buttonStyle(.borderedProminent)
}
}