English 中文(简体)
SwiftUI Transactions: Making a button that either animates or is still, based on external state
原标题:

I m trying to make a view that conditionally animates (repeating forever) based on the state of another view.

This below button does it all in one view... but that state is all internal. I want it to be 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()
            }
        }
    }
}

I tried to do it like this, using the Transactions API. However, this just has the effect of doing weird animations when I tap, basically doing some sort of weird wobbling like motion.

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
                }
            }
    }
}

Any ideas on how to fix it?

问题回答

You could do something like below, where you re setting what animation you want to use based on active. I don t believe you can stop the repeatForever animation by setting it to nil, you actually need to update it to default...

Alternatively, you could write an extension on Animation to make this a little cleaner/reusable. But at a quick test, the below starts and stops the animation as I believe you are attempting to do.

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)
    }
}




相关问题
images sliding continuously with <table> and jQuery

I m trying to write a little test page that circulates images through a window (see image). I have colored boxes inside a table (gray border), with each box being a element. <table id="boxes" ...

WPF 3d rotation animations

I have a few 3d rectangles on my screen that I want to pivot around the Y axis. I want to press down with the mouse, and rotate the 3d object to a max rotation, but when the user moves their mouse, ...

Disable Windows 7 touch animation in WPF

In Windows 7 when you touch the screen there is a short animation that occurs at the touch point. In my WPF app I want to display my own touch points, without showing the one supplied by Windows. ...

jQuery block moving

I wanna move a div block to the top, so I coded like this: CSS part: .movingPart{ margin-top:80px; } jQuery part: $(document).ready(function() { $( #btn ).click(function() { $( .movingPart )....

Direct 2D gnuplot PNG animation?

Can anyone please confirm that yes/no Gnuplot 4.5 (on CVS) can output 2D animated PNG files? I have numerous datasets but one line that I d like to show iteratively in 3 different places in my graph. ...

Visual State Manager VS Animations in WPF

There is a lot of talk about the simplicity of Visual States and the transitions between them in WPF/Silverlight. I have the need to generate animations dynamically at runtime, to animate the ...

Create a ImageIcon that is the mirror of another one

I ll like to know if there is a way to create a ImageIcon that is the mirror of another ImageIcon. Searching on Google, I found how to do it by using many AWT libraries. Is there a way to do it with ...

how to drag in the animation in iphone application?

Iphone application is using the static co-ordinates to reach at some points in the application,which is based on the button event. But what i want is when i drag the item than it should reach at some ...

热门标签