Fond d'écran iPhone SE 2022 dans SwiftUI

Fond d’écran iPhone SE 2022 dans SwiftUI

La semaine dernière, j’ai écrit un tutoriel sur la création du nouveau fond d’écran Apple iPhone SE à l’aide de Photoshop. C’était un petit tutoriel vraiment amusant et j’ai aussi vu un autre designer faire le même effet dans Figma. C’est incroyable de voir tant de personnes talentueuses ainsi que des outils incroyables à notre disposition. Avec la même image en tête, j’ai décidé d’essayer de la recréer en code en utilisant SwiftUI et cela s’avère être un exercice amusant avec un très beau résultat.

Remarque : il y a des bandes sur le dégradé. Mes connaissances sont limitées sur SwiftUI mais je suis sûr qu’il existe une solution. Il y a aussi un bug bizarre dans mon animation, mais ce n’est pas vraiment nécessaire. Voici donc ce que j’ai fait.

Aperçu vidéo

Étape 1

Commencez avec la vue rectangle simple. J’ai appelé ma structure ColorBar

struct ColorBar: View {
       var body: some View {
        Rectangle()  
    }
}

Étape 2

Ensuite, j’ai créé 5 variables différentes pour les dégradés et appliqué au remplissage de mon rectangle. Les première et dernière couleurs que j’ai utilisées 0 pour l’opacité. Assurez-vous également que startPoint est .top et endPoint est .bottom.

struct ColorBar: View {
    var g1:Color = Color(red: 95 / 255, green: 71 / 255, blue: 202 / 255)
    var g2:Color = Color(red: 255 / 255, green: 175 / 255, blue: 196 / 255)
    var g3:Color = Color(red: 230 / 255, green: 210 / 255, blue: 173 / 255)
    var g4:Color = Color(red: 244 / 255, green: 160 / 255, blue: 18 / 255)
    var g5:Color = Color(red: 228 / 255, green:0 / 255, blue: 0 / 255)
    var body: some View {
        Rectangle().fill(
            LinearGradient(gradient: Gradient(colors: [g1.opacity(0),g1,g2,g3,g4,g5,g5.opacity(0)]), startPoint: .top, endPoint: .bottom))
        
    }
}

Étape 3

Tout mettre ensemble. J’ai d’abord tout fait manuellement, c’est-à-dire que j’ai ajouté 9 instances de ma barre de couleurs et modifié la valeur de leur hauteur à l’aide du modificateur de cadre. J’ai créé une simple variable appelée multiplicateur à utiliser comme base pour la différence de hauteur.

struct ManualBars: View{
    var multiplier:CGFloat = 60
    var body: some View{
        GeometryReader { geometry in
            HStack(alignment: .center, spacing:0){
                ColorBar().frame(height: geometry.size.height - (multiplier * 1)).zIndex(5)
                ColorBar().frame(height: geometry.size.height - (multiplier * 2)).zIndex(4)
                ColorBar().frame(height: geometry.size.height - (multiplier * 3)).zIndex(3)
                ColorBar().frame(height: geometry.size.height - (multiplier * 4)).zIndex(2)
                ColorBar().frame(height: geometry.size.height - (multiplier * 5))
                ColorBar().frame(height: geometry.size.height - (multiplier * 4)).zIndex(2)
                ColorBar().frame(height: geometry.size.height - (multiplier * 3)).zIndex(3)
                ColorBar().frame(height: geometry.size.height - (multiplier * 2)).zIndex(4)
                ColorBar().frame(height: geometry.size.height - (multiplier * 1)).zIndex(5)
            }
        }
    }
}

Conclusion

Après cela, je passe un peu plus de temps à essayer d’automatiser le processus avec ForEach. J’ai toujours du mal avec le concept, mais voici le code final. Ah ! J’ai également animé les barres lorsque l’application s’ouvre ainsi que lorsque vous appuyez dessus.

//
//  ContentView.swift
//  SEBG
//
//  Created by Fabio Sasso on 3/12/22.
//
import SwiftUI

struct ContentView: View {
    var multiplier:CGFloat = 60
    var steps:Int = 9
    var half:Int = 5
    var gStart:Color  = Color(red: 29 / 255, green: 6 / 255, blue: 74 / 255)
    var gEnd:Color  = Color(red: 54 / 255, green: 4 / 255, blue: 2 / 255)
    @State var aniBar: Bool = false
    var body: some View {
        GeometryReader { geometry in
            ZStack{
                HStack(alignment: .center, spacing:0){
                    ForEach((1...steps), id: .self) { i in
                        if(i <= half){
                            ColorBar().frame(height: self.aniBar ? geometry.size.height - (multiplier * CGFloat(i)) : geometry.size.height).zIndex(Double(half - (i-half))).shadow(color: Color.black.opacity(self.aniBar ? 0.1 : 0),radius: 5 ).animation(Animation.easeInOut(duration:4))
                            //geometry.size.height - (multiplier * CGFloat(i))
                        }
                        else{
                            ColorBar().frame(height: self.aniBar ? geometry.size.height - (multiplier * CGFloat(half - (i-half))) : geometry.size.height).zIndex(Double(i)).shadow(color: Color.black.opacity(self.aniBar ? 0.1 : 0),radius: 5 ).animation(Animation.easeInOut(duration:4))
                        }
                    }
                }.frame(height: geometry.size.height)
            }.background(LinearGradient(gradient: Gradient(colors: [gStart,gEnd]), startPoint: .top, endPoint: .bottom))
        }.edgesIgnoringSafeArea(.all)
            .onAppear{
                self.aniBar.toggle()
            }
            .onTapGesture{
                self.aniBar.toggle()
            }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
struct ColorBar: View {
    var g1:Color = Color(red: 95 / 255, green: 71 / 255, blue: 202 / 255)
    var g2:Color = Color(red: 255 / 255, green: 175 / 255, blue: 196 / 255)
    var g3:Color = Color(red: 230 / 255, green: 210 / 255, blue: 173 / 255)
    var g4:Color = Color(red: 244 / 255, green: 160 / 255, blue: 18 / 255)
    var g5:Color = Color(red: 228 / 255, green:0 / 255, blue: 0 / 255)
    var body: some View {
        Rectangle().fill(
            LinearGradient(gradient: Gradient(colors: [g1.opacity(0),g1,g2,g3,g4,g5,g5.opacity(0)]), startPoint: .top, endPoint: .bottom))
        
    }
}

Vous pouvez également le télécharger via GitHub ici et essayez également sur votre iPad avec Playgrounds.