J'ai commencé à explorer SwiftUI et je ne trouve pas de moyen d'obtenir une chose simple: je voudrais qu'une vue ait une hauteur proportionnelle (essentiellement un pourcentage de la hauteur de son parent). Disons que j'ai 3 vues empilées verticalement. Je voudrais:
J'ai regardé cette vidéo intéressante de la WWDC19 sur les vues personnalisées dans SwiftUI ( https://developer.Apple.com/videos/play/wwdc2019/237/ ) et j'ai compris (corrigez-moi si je suis mal) que, fondamentalement, une vue n'a jamais de taille en soi, la taille est la taille de ses enfants. Ainsi, la vue des parents demande à ses enfants de quelle taille ils sont. Ils répondent à quelque chose comme: "la moitié de votre taille!" et maintenant quoi? Comment le système de mise en page (qui est différent du système de mise en page que nous utilisions auparavant) gère-t-il cette situation?
Si vous écrivez le code ci-dessous:
struct ContentView : View {
var body: some View {
VStack(spacing: 0) {
Rectangle()
.fill(Color.red)
Rectangle()
.fill(Color.green)
Rectangle()
.fill(Color.yellow)
}
}
}
Le système de mise en page SwiftUI dimensionne chaque vue pour qu'elle soit 1/3 de haut et cela correspond à la vidéo que j'ai publiée ci-dessus. Vous pouvez envelopper les rectangles dans un cadre de cette façon:
struct ContentView : View {
var body: some View {
VStack(spacing: 0) {
Rectangle()
.fill(Color.red)
.frame(height: 200)
Rectangle()
.fill(Color.green)
.frame(height: 400)
Rectangle()
.fill(Color.yellow)
}
}
}
De cette façon, le système de mise en page dimensionne le premier rectangle à 200 de haut, le second à 400 de haut et le troisième à tout l'espace gauche. Et encore une fois, ça va. Ce que vous ne pouvez pas faire (de cette façon), c'est spécifier une hauteur proportionnelle.
Vous pouvez utiliser GeometryReader
. Enveloppez le lecteur autour de toutes les autres vues et utilisez sa valeur de fermeture metrics
pour calculer les hauteurs:
let propHeight = metrics.size.height * 0.43
Utilisez-le comme suit:
import SwiftUI
struct ContentView: View {
var body: some View {
GeometryReader { metrics in
VStack(spacing: 0) {
Color.red.frame(height: metrics.size.height * 0.43)
Color.green.frame(height: metrics.size.height * 0.37)
Color.yellow
}
}
}
}
import PlaygroundSupport
PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())