Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to animate a menu from circle to oval like this?

Consider this code:

import SwiftUI

struct ContentView: View {
  @State private var hidden = true
    var body: some View {
        HStack {
          Group{
            if !hidden {
              Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(Color.black)
                .font(.system(size: 50))
                .opacity(hidden ? 0 : 1)
                .animation(.easeInOut(duration: 0.5).delay(1), value: hidden)
            }
            Image(systemName: "globe")
              .imageScale(.large)
              .foregroundStyle(Color.white)
              .font(.system(size: 50))
            
            if !hidden {
              Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(Color.yellow)
                .font(.system(size: 50))
                .opacity(hidden ? 0 : 1)
                .animation(.easeInOut(duration: 0.5).delay(3), value: hidden)    
            }
          }
          .padding(.horizontal, 10)
          .padding(.vertical, 5)              
        }
        .onTapGesture {
          withAnimation{
            hidden.toggle()
          }
        }
        .background(
          RoundedRectangle(cornerSize: CGSize(width: 50,height: 50))
            .fill(.red)
        )
        .padding()
    }
}

#Preview {
    ContentView()
}

This code shows a white globe over a white circle like this, initially.

enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

When you tap the circle the menu expands to be an ellipse with two other globes on it.

enter image description here

The black and the yellow globes appear fade in at the same time the ellipse is expanding but this is not what I want.

I want all globes to be piled at the same central position. At this point, only the central globe is visible and the other two are invisible. As the red circle is tapped and begins to expand, I want globe 1 to move to the left and globe 3 to move to the right, as they were chasing the new border which is expanding. At the same time they are moving they are changing transparency to 1.

If the now ellipse is tapped, I want the reverse to happen.

how do I do that?

>Solution :

Instead of animations, transactions are way better at this. Because they are made for animating hiding and showing of views.

Result

struct ContentView: View {
  @State private var hidden = true
    
    var body: some View {
        HStack {
            Group {
                if !hidden {
                    Image(systemName: "globe")
                        .imageScale(.large)
                        .foregroundStyle(Color.black)
                        .font(.system(size: 50))
                        .zIndex(0)
                        .transition(.offset(x: 100, y: 0).combined(with: .opacity))
                }
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(Color.white)
                    .font(.system(size: 50))
                    .zIndex(1)
                
                if !hidden {
                    Image(systemName: "globe")
                        .imageScale(.large)
                        .foregroundStyle(Color.yellow)
                        .font(.system(size: 50))
                        .font(.system(size: 50))
                        .zIndex(0)
                        .transition(.offset(x: -100, y: 0).combined(with: .opacity))
                }
            }
            .padding(.horizontal, 10)
            .padding(.vertical, 5)
        }
        .onTapGesture {
            withAnimation{
                hidden.toggle()
            }
        }
        .background(
            RoundedRectangle(cornerSize: CGSize(width: 50,height: 50))
                .fill(.red)
        )
        .padding()
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading