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.