我正在try 创建一个基于另一个视图的状态有条件地设置动画(永远重复)的视图.

下面的按钮可以在一个视图中完成所有操作...但这个州都是internal.我希望是external.

struct ButtonBouncerView: View {
    @State var active: Bool = false

    var body: some View {
        Circle()
            .scaleEffect(active ? 1.08: 1)
            .animation(Animation.default.repeatForever(autoreverses: true), value: active)
            .frame(width: 100, height: 100)
            .onTapGesture {
                useTransaction()
            }
            .onAppear {
                active = true
            }
    }

    func useTransaction() {
        var transaction = Transaction()
        transaction.disablesAnimations = active ? true : false

        withTransaction(transaction) {
            withAnimation {
                active.toggle()
            }
        }
    }
}

我试着这样做,使用事务API.然而,当我敲击时,这只会产生奇怪的动画效果,基本上是某种奇怪的摇摆,比如运动.

struct OutsideControllableButtonView: View {
    @State private var active: Bool = false

    var body: some View {
        VStack {
            OutsideControllableButtonScaler(active: $active)
            Button(action: { // CONTROLLER BUTTON!
                active.toggle()
            }) {
                Text("Control Button")
            }
            .padding()
            .background(Color.green)
            .foregroundColor(.white)
        }
    }
}

struct OutsideControllableButtonScaler: View {
    // When Active, the button
    @Binding var active: Bool

    var body: some View {
        Circle()
            .scaleEffect(active ? 1.08: 1)
            .animation(Animation.default.repeatForever(autoreverses: true), value: active)
            .frame(width: 100, height: 100)
            .onChange(of: active) { newValue in
                var transaction = Transaction(animation: newValue ? Animation.default.repeatForever(autoreverses: true) : nil)
                transaction.disablesAnimations = true
                withTransaction(transaction) {
                    self.active = newValue
                }
            }
    }
}

你有什么办法解决这个问题吗?

推荐答案

你可以像下面这样做,在那里你可以设置你想要使用的基于active的动画.我不相信你可以通过将Repever Forever动画设置为零来停止它,你实际上需要将它更新为默认设置…

或者,您可以在Animation上编写一个扩展以使其更干净/更可重用.但在一个快速测试,下面开始和停止动画,我相信你正在try 这样做.

struct OutsideControllableButtonView: View {
    @State private var active: Bool = false
    
    var body: some View {
        VStack {
            OutsideControllableButtonScaler(active: $active)
            Button(action: { // CONTROLLER BUTTON!
                self.active.toggle()
            }) {
                Text("Control Button")
            }
            .padding()
            .background(Color.green)
            .foregroundColor(.white)
        }
    }
}

struct OutsideControllableButtonScaler: View {
    // When Active, the button
    @Binding var active: Bool
    
    var body: some View {
        Circle()
            .scaleEffect(active ? 1.08 : 1)
            .animation(active ? Animation.default.repeatForever(autoreverses: true) : .default, value: active)
            .frame(width: 100, height: 100)
    }
}

Swift相关问答推荐

如何在visionOS中定制悬停效果区域

在NavigationStack上设置拐角半径:SwiftUI中的无响应内容视图区

使 tabview 垂直将视图移动到右侧 swift ui

Swift ui 转换无法按预期工作

物理主体未与 spritekit Swift 的网格图案上的纹理图像对齐

如何根据 DatePicker 中选定的日期实现 TabView 页面切换?

计算 CoreData 中所有唯一对象的数量?

使用变量(而非固定)的字符串分量进行Swift正则表达式

Swift计时器未触发

如何制作一个在 SceneKit 中投射阴影的透明物体?

避免 `(())` 显式指定 Void 类型的枚举关联值

为什么 NumberFormatter 在 Swift 中将 19,999,999,999,999,999 格式化为 20,000,000,000,000,000?

快速更改tableView中的数据

如何确定扩展中的具体类型?

使 Picker 与其他 BinaryInteger 类型兼容

如何在 RxSwift 中获取 controlEvent 类型?

Vapor - 流利的,将对象保存到 PostgreSQL

如何使被拖动的对象成为前景(foreground)对象

不支持用作符合协议 AnyObject 的具体类型

CMutablePointer - 如何访问它?