Using the full, 2960x1440 wallpapers with LazyVGrid is not an option, as it leads to unsatisfactory performance, even on an iPhone 12 Pro.
All assets are stored in the asset catalog. These are the Models:
struct Thumbnail: Identifiable {
var id = UUID()
var name: String
}
struct Wallpaper: Identifiable {
var id = UUID()
var name: String
}
let thumbnailSet = (1...50).map { Thumbnail(name: "thumbnail-\($0)") }
let wallpaperSet = (1...50).map { Wallpaper(name: "wallpaper-\($0)") }
The gallery is a simple two column grid:
import SwiftUI
struct GalleryView: View {
@State private var fullScreen = false
let columns = [
GridItem(.flexible(), spacing: 2),
GridItem(.flexible())]
var body: some View {
ZStack {
// GRID VIEW
ScrollView(showsIndicators: false) {
VStack {
LazyVGrid(columns: columns, spacing: 2) {
ForEach(thumbnailSet.indices) { index in
Image(thumbnailSet[index].name)
.resizable()
.aspectRatio(contentMode: .fit)
.onTapGesture {(fullScreen = true)}
}
}
}
}
.ignoresSafeArea()
// FULL SCREEN VIEW
if fullScreen {
ZStack {
// Code to show corresponding wallpaper?
// BACK TO GRID VIEW
Button(action: {
(fullScreen = false)
}) {Image(systemName: "chevron.left")
.font(.system(size: 23))
.frame(width: 48, height: 44)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
.zIndex(1)
}
}
}
}
Is this doable? Ideas?
Thank you!
You can make your fullscreen
an optional index and use that to switch and show the respective wallpaper image:
EDIT: now with animation
struct GalleryView: View {
@State private var fullScreen: Int? = nil // make it an optional index
@Namespace var namespace
let columns = [
GridItem(.flexible(), spacing: 2),
GridItem(.flexible())]
var body: some View {
ZStack {
// GRID VIEW
ScrollView(showsIndicators: false) {
VStack {
LazyVGrid(columns: columns, spacing: 2) {
ForEach(thumbnailSet.indices) { index in
let fullscreenIndex = fullScreen ?? -1
if index == fullscreenIndex {
Color.white
} else {
Image(thumbnailSet[index].name)
.resizable()
.aspectRatio(1, contentMode: .fill)
.clipped()
.matchedGeometryEffect(id: index, in: namespace)
.onTapGesture {
withAnimation {
fullScreen = index // set index here
}
}
}
}
}
}
}
.ignoresSafeArea()
// FULL SCREEN VIEW
if let fullscreenIndex = fullScreen {
ZStack {
Color.white
.ignoresSafeArea()
// show image based on set index
Image(wallpaperSet[fullscreenIndex].name)
.resizable()
.aspectRatio(contentMode: .fit)
.matchedGeometryEffect(id: fullscreenIndex, in: namespace)
// BACK TO GRID VIEW
Button(action: {
withAnimation {
fullScreen = nil
}
}) {Image(systemName: "chevron.left")
.font(.system(size: 23))
.frame(width: 48, height: 44)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
.zIndex(1)
}
}
}
}