Expand image when 'popped' out by Context Menu SwiftUI

63 Views Asked by At

I am trying to achieve the functionality you get in the Photos app when you press and hold on an image. A context menu appears with various options (copy, share, favourite etc..) however the main but I'm trying to replicate is the fact that the image expands from the grid into a larger sized version.

This is what I am trying to achieve:

Photos app context menu behaviour

This is what my app currently does:

My app context menu behaviour

The code I have for my app is below

let columns = [
    GridItem(.adaptive(minimum: 100), spacing: 2),
    GridItem(.adaptive(minimum: 100), spacing: 2),
    GridItem(.adaptive(minimum: 100), spacing: 2),
    GridItem(.adaptive(minimum: 100), spacing: 2),
    GridItem(.adaptive(minimum: 100), spacing: 2)
]


var body: some View {
    ScrollView {
        LazyVGrid(columns: columns, spacing: 2) {
            ForEach(imageUrls, id: \.self) { imageUrl in
                AsyncImage(url: imageUrl) { image in
                    image
                        .resizable()
                        .aspectRatio(1, contentMode: .fill)
                        .contextMenu {
                            Button {
                                print("Save image")
                            } label: {
                                Label("Save to Photos", systemImage: "square.and.arrow.down")
                            }

                        }
                } placeholder: {
                    ProgressView()
                }
            }
        }
    }

I have thought about the possible need to track a state of whether or not an image in 'in context menu mode' or not, and if so, increase the size, however I would presume this would mess up the grid and I'm not sure if it's possible to track a state like that.

Any help with this would be greatly appreciated.

1

There are 1 best solutions below

0
Mahi Al Jawad On

First of all as I don't have your image data so I could not share my answer with your code. I'm showing an example I have made to answer your question.

You can use the modifier contextMenu with preview option.

preview basically returns a new view when you long press in the view item. So you can show whatever you wish.

You just need to show a view with a larger size. Which you can do in many ways. I'm showing an example for this:

import SwiftUI

struct ContentView: View {
    var image: some View {
        Image(systemName: "sun.max.fill")
            .resizable()
            .padding()
            .background(.cyan)
            .foregroundStyle(.orange)
            
    }
    var body: some View {
        image
            .frame(width: 200, height: 200)
            // Here is your real answer
            .contextMenu {
                Button(action: {
                }) {
                    Label("Save", systemImage: "square.and.arrow.up")
                }
                Button(action: {
                }) {
                    Label("Edit", systemImage: "square.and.arrow.up")
                }
            } preview: {
               // I used `withAnimation` so that the change looks smooth
               // I'm just showing an increased size image inside preview
                withAnimation {
                    image
                        .frame(width: 400, height: 400)
                }
            }
    }
}

Simulation:

enter image description here

Hope you can infer your answer.